Skip to content

Commit a7bd974

Browse files
Fix: avoid using obsolete AesGcm (#4165)
Co-authored-by: Christopher Schuchardt <[email protected]>
1 parent 8afce40 commit a7bd974

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

src/Neo/Cryptography/Helper.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public static class Helper
3232
{
3333
private static readonly bool s_isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
3434

35+
private const int AesNonceSizeBytes = 12;
36+
private const int AesTagSizeBytes = 16;
37+
3538
/// <summary>
3639
/// Computes the hash value for the specified byte array using the ripemd160 algorithm.
3740
/// </summary>
@@ -229,22 +232,22 @@ public static byte[] Keccak256(this Span<byte> value)
229232

230233
public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] nonce, byte[] associatedData = null)
231234
{
232-
if (nonce.Length != 12) throw new ArgumentOutOfRangeException(nameof(nonce), "`nonce` must be 12 bytes");
233-
var tag = new byte[16];
235+
if (nonce.Length != AesNonceSizeBytes)
236+
throw new ArgumentOutOfRangeException(nameof(nonce), $"`nonce` must be {AesNonceSizeBytes} bytes");
237+
238+
var tag = new byte[AesTagSizeBytes];
234239
var cipherBytes = new byte[plainData.Length];
235240
if (!s_isOSX)
236241
{
237-
#pragma warning disable SYSLIB0053 // Type or member is obsolete
238-
using var cipher = new AesGcm(key);
239-
#pragma warning restore SYSLIB0053 // Type or member is obsolete
242+
using var cipher = new AesGcm(key, AesTagSizeBytes);
240243
cipher.Encrypt(nonce, plainData, cipherBytes, tag, associatedData);
241244
}
242245
else
243246
{
244247
var cipher = new GcmBlockCipher(new AesEngine());
245248
var parameters = new AeadParameters(
246249
new KeyParameter(key),
247-
128, //128 = 16 * 8 => (tag size * 8)
250+
AesTagSizeBytes * 8, // 128 = 16 * 8 => (tag size * 8)
248251
nonce,
249252
associatedData);
250253
cipher.Init(true, parameters);
@@ -257,24 +260,25 @@ public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] non
257260

258261
public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[] associatedData = null)
259262
{
263+
if (encryptedData.Length < AesNonceSizeBytes + AesTagSizeBytes)
264+
throw new ArgumentException($"The encryptedData.Length must be greater than {AesNonceSizeBytes} + {AesTagSizeBytes}");
265+
260266
ReadOnlySpan<byte> encrypted = encryptedData;
261-
var nonce = encrypted[..12];
262-
var cipherBytes = encrypted[12..^16];
263-
var tag = encrypted[^16..];
267+
var nonce = encrypted[..AesNonceSizeBytes];
268+
var cipherBytes = encrypted[AesNonceSizeBytes..^AesTagSizeBytes];
269+
var tag = encrypted[^AesTagSizeBytes..];
264270
var decryptedData = new byte[cipherBytes.Length];
265271
if (!s_isOSX)
266272
{
267-
#pragma warning disable SYSLIB0053 // Type or member is obsolete
268-
using var cipher = new AesGcm(key);
269-
#pragma warning restore SYSLIB0053 // Type or member is obsolete
273+
using var cipher = new AesGcm(key, AesTagSizeBytes);
270274
cipher.Decrypt(nonce, cipherBytes, tag, decryptedData, associatedData);
271275
}
272276
else
273277
{
274278
var cipher = new GcmBlockCipher(new AesEngine());
275279
var parameters = new AeadParameters(
276280
new KeyParameter(key),
277-
128, //128 = 16 * 8 => (tag size * 8)
281+
AesTagSizeBytes * 8, // 128 = 16 * 8 => (tag size * 8)
278282
nonce.ToArray(),
279283
associatedData);
280284
cipher.Init(false, parameters);

tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,17 @@ public class UT_Cryptography_Helper
3030
public void TestBase58CheckDecode()
3131
{
3232
string input = "3vQB7B6MrGQZaxCuFg4oh";
33-
byte[] result = input.Base58CheckDecode();
33+
var result = input.Base58CheckDecode();
3434
byte[] helloWorld = { 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 };
3535
CollectionAssert.AreEqual(helloWorld, result);
3636

3737
input = "3v";
38-
Action action = () => input.Base58CheckDecode();
38+
var action = () => input.Base58CheckDecode();
3939
Assert.ThrowsExactly<FormatException>(action);
4040

4141
input = "3vQB7B6MrGQZaxCuFg4og";
4242
action = () => input.Base58CheckDecode();
4343
Assert.ThrowsExactly<FormatException>(action);
44-
4544
Assert.ThrowsExactly<FormatException>(() => _ = string.Empty.Base58CheckDecode());
4645
}
4746

@@ -90,20 +89,22 @@ public void TestKeccak256()
9089
public void TestRIPEMD160()
9190
{
9291
ReadOnlySpan<byte> value = Encoding.ASCII.GetBytes("hello world");
93-
byte[] result = value.RIPEMD160();
92+
var result = value.RIPEMD160();
9493
Assert.AreEqual("98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f", result.ToHexString());
9594
}
9695

9796
[TestMethod]
9897
public void TestAESEncryptAndDecrypt()
9998
{
100-
NEP6Wallet wallet = new NEP6Wallet("", "1", TestProtocolSettings.Default);
99+
var wallet = new NEP6Wallet("", "1", TestProtocolSettings.Default);
101100
wallet.CreateAccount();
102-
WalletAccount account = wallet.GetAccounts().ToArray()[0];
103-
KeyPair key = account.GetKey();
104-
Random random = new Random();
105-
byte[] nonce = new byte[12];
101+
102+
var account = wallet.GetAccounts().ToArray()[0];
103+
var key = account.GetKey();
104+
var random = new Random();
105+
var nonce = new byte[12];
106106
random.NextBytes(nonce);
107+
107108
var cypher = Helper.AES256Encrypt(Encoding.UTF8.GetBytes("hello world"), key.PrivateKey, nonce);
108109
var m = Helper.AES256Decrypt(cypher, key.PrivateKey);
109110
var message2 = Encoding.UTF8.GetString(m);
@@ -113,35 +114,41 @@ public void TestAESEncryptAndDecrypt()
113114
[TestMethod]
114115
public void TestEcdhEncryptAndDecrypt()
115116
{
116-
NEP6Wallet wallet = new NEP6Wallet("", "1", ProtocolSettings.Default);
117+
var wallet = new NEP6Wallet("", "1", ProtocolSettings.Default);
117118
wallet.CreateAccount();
118119
wallet.CreateAccount();
119-
WalletAccount account1 = wallet.GetAccounts().ToArray()[0];
120-
KeyPair key1 = account1.GetKey();
121-
WalletAccount account2 = wallet.GetAccounts().ToArray()[1];
122-
KeyPair key2 = account2.GetKey();
120+
121+
var account1 = wallet.GetAccounts().ToArray()[0];
122+
var key1 = account1.GetKey();
123+
var account2 = wallet.GetAccounts().ToArray()[1];
124+
var key2 = account2.GetKey();
123125
Console.WriteLine($"Account:{1},privatekey:{key1.PrivateKey.ToHexString()},publicKey:{key1.PublicKey.ToArray().ToHexString()}");
124126
Console.WriteLine($"Account:{2},privatekey:{key2.PrivateKey.ToHexString()},publicKey:{key2.PublicKey.ToArray().ToHexString()}");
127+
125128
var secret1 = Helper.ECDHDeriveKey(key1, key2.PublicKey);
126129
var secret2 = Helper.ECDHDeriveKey(key2, key1.PublicKey);
127130
Assert.AreEqual(secret1.ToHexString(), secret2.ToHexString());
131+
128132
var message = Encoding.ASCII.GetBytes("hello world");
129-
Random random = new Random();
130-
byte[] nonce = new byte[12];
133+
var random = new Random();
134+
var nonce = new byte[12];
131135
random.NextBytes(nonce);
136+
132137
var cypher = message.AES256Encrypt(secret1, nonce);
133138
cypher.AES256Decrypt(secret2);
134139
Assert.AreEqual("hello world", Encoding.ASCII.GetString(cypher.AES256Decrypt(secret2)));
140+
141+
Assert.ThrowsExactly<ArgumentException>(() => Helper.AES256Decrypt(new byte[11], key1.PrivateKey));
142+
Assert.ThrowsExactly<ArgumentException>(() => Helper.AES256Decrypt(new byte[11 + 16], key1.PrivateKey));
135143
}
136144

137145
[TestMethod]
138146
public void TestTest()
139147
{
140148
int m = 7, n = 10;
141149
uint nTweak = 123456;
142-
BloomFilter filter = new(m, n, nTweak);
143-
144-
Transaction tx = new()
150+
var filter = new BloomFilter(m, n, nTweak);
151+
var tx = new Transaction()
145152
{
146153
Script = TestUtils.GetByteArray(32, 0x42),
147154
SystemFee = 4200000000,

0 commit comments

Comments
 (0)