Skip to content

Commit bef9609

Browse files
committed
VerifyKeysAreNotTooSimilar
1 parent 885741c commit bef9609

File tree

3 files changed

+71
-28
lines changed

3 files changed

+71
-28
lines changed

src/NServiceBus.Core.Tests/Encryption/EncryptionServiceTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,18 @@ public void Should_throw_when_decrypt_with_wrong_key()
7777
}
7878
}
7979

80+
[Test]
81+
public void Should_throw_when_encrypt_and_decrypt_keys_are_too_similar()
82+
{
83+
var key = Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6");
84+
var service = new EncryptionService
85+
{
86+
Key = key,
87+
ExpiredKeys = new List<byte[]> { key } //note that we use the same key to get the code to throw
88+
};
89+
var exception = Assert.Throws<Exception>(service.VerifyKeysAreNotTooSimilar);
90+
91+
Assert.AreEqual("The new Encryption Key is too similar to the Expired Key at index 0. This can cause issues when decrypting data. To fix this issue please ensure the new encryption key is not too similar to the existing Expired Keys.", exception.Message);
92+
}
8093
}
8194
}

src/NServiceBus.Core/ConfigureRijndaelEncryptionService.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace NServiceBus
55
using System.Linq;
66
using System.Text;
77
using Config;
8+
using Encryption;
89
using Encryption.Rijndael;
910
using Logging;
1011

@@ -25,7 +26,7 @@ public static Configure RijndaelEncryptionService(this Configure config)
2526
if (section == null)
2627
Logger.Warn("Could not find configuration section for Rijndael Encryption Service.");
2728

28-
var encryptConfig = config.Configurer.ConfigureComponent<EncryptionService>(DependencyLifecycle.SingleInstance);
29+
var encryptionService = new EncryptionService();
2930

3031
if (section != null)
3132
{
@@ -34,10 +35,15 @@ public static Configure RijndaelEncryptionService(this Configure config)
3435
throw new Exception("The RijndaelEncryptionServiceConfig has an empty 'Key' attribute.");
3536
}
3637
var expiredKeys = ExtractExpiredKeysFromConfigSection(section);
37-
encryptConfig.ConfigureProperty(s => s.Key, Encoding.ASCII.GetBytes(section.Key));
38-
encryptConfig.ConfigureProperty(s => s.ExpiredKeys, expiredKeys.Select(x=>Encoding.ASCII.GetBytes(x)).ToList());
38+
39+
encryptionService.Key = Encoding.ASCII.GetBytes(section.Key);
40+
encryptionService.ExpiredKeys = expiredKeys.Select(x => Encoding.ASCII.GetBytes(x)).ToList();
3941
}
4042

43+
encryptionService.VerifyKeysAreNotTooSimilar();
44+
45+
config.Configurer.RegisterSingleton<IEncryptionService>(encryptionService);
46+
4147
return config;
4248
}
4349

@@ -68,4 +74,4 @@ internal static List<string> ExtractExpiredKeysFromConfigSection(RijndaelEncrypt
6874
}
6975
private static readonly ILog Logger = LogManager.GetLogger(typeof(RijndaelEncryptionServiceConfig));
7076
}
71-
}
77+
}

src/NServiceBus.Core/Encryption/Rijndael/EncryptionService.cs

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,42 +31,43 @@ string IEncryptionService.Decrypt(EncryptedValue encryptedValue)
3131
return encryptedValue.EncryptedBase64Value;
3232
}
3333

34-
var decryptionKeys = new List<byte[]>{Key};
34+
var decryptionKeys = new List<byte[]> { Key };
3535
if (ExpiredKeys != null)
3636
{
3737
decryptionKeys.AddRange(ExpiredKeys);
3838
}
39-
var encrypted = Convert.FromBase64String(encryptedValue.EncryptedBase64Value);
4039
var cryptographicExceptions = new List<CryptographicException>();
41-
using (var rijndael = new RijndaelManaged())
42-
{
43-
rijndael.IV = Convert.FromBase64String(encryptedValue.Base64Iv);
44-
rijndael.Mode = CipherMode.CBC;
4540

46-
foreach (var key in decryptionKeys)
41+
foreach (var key in decryptionKeys)
42+
{
43+
try
4744
{
48-
rijndael.Key = key;
49-
try
50-
{
51-
return Decrypt(rijndael, encrypted);
52-
}
53-
catch (CryptographicException exception)
54-
{
55-
cryptographicExceptions.Add(exception);
56-
}
45+
return Decrypt(encryptedValue, key);
46+
}
47+
catch (CryptographicException exception)
48+
{
49+
cryptographicExceptions.Add(exception);
5750
}
5851
}
5952
var message = string.Format("Could not decrypt message. Tried {0} keys.", decryptionKeys.Count);
6053
throw new AggregateException(message, cryptographicExceptions);
6154
}
62-
static string Decrypt(RijndaelManaged rijndael, byte[] encrypted)
55+
56+
static string Decrypt(EncryptedValue encryptedValue, byte[] key)
6357
{
64-
using (var decryptor = rijndael.CreateDecryptor())
65-
using (var memoryStream = new MemoryStream(encrypted))
66-
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
67-
using (var reader = new StreamReader(cryptoStream))
58+
using (var rijndael = new RijndaelManaged())
6859
{
69-
return reader.ReadToEnd();
60+
var encrypted = Convert.FromBase64String(encryptedValue.EncryptedBase64Value);
61+
rijndael.IV = Convert.FromBase64String(encryptedValue.Base64Iv);
62+
rijndael.Mode = CipherMode.CBC;
63+
rijndael.Key = key;
64+
using (var decryptor = rijndael.CreateDecryptor())
65+
using (var memoryStream = new MemoryStream(encrypted))
66+
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
67+
using (var reader = new StreamReader(cryptoStream))
68+
{
69+
return reader.ReadToEnd();
70+
}
7071
}
7172
}
7273

@@ -99,6 +100,29 @@ EncryptedValue IEncryptionService.Encrypt(string value)
99100
}
100101
}
101102

102-
private static readonly ILog Logger = LogManager.GetLogger(typeof (EncryptionService));
103+
internal void VerifyKeysAreNotTooSimilar()
104+
{
105+
for (var index = 0; index < ExpiredKeys.Count; index++)
106+
{
107+
var decryption = ExpiredKeys[index];
108+
CryptographicException exception = null;
109+
var encryptedValue = ((IEncryptionService)this).Encrypt("a");
110+
try
111+
{
112+
Decrypt(encryptedValue, decryption);
113+
}
114+
catch (CryptographicException cryptographicException)
115+
{
116+
exception = cryptographicException;
117+
}
118+
if (exception == null)
119+
{
120+
var message = string.Format("The new Encryption Key is too similar to the Expired Key at index {0}. This can cause issues when decrypting data. To fix this issue please ensure the new encryption key is not too similar to the existing Expired Keys.", index);
121+
throw new Exception(message);
122+
}
123+
}
124+
}
125+
126+
static readonly ILog Logger = LogManager.GetLogger(typeof(EncryptionService));
103127
}
104-
}
128+
}

0 commit comments

Comments
 (0)