Skip to content

Latest commit

 

History

History
52 lines (40 loc) · 2.46 KB

README.md

File metadata and controls

52 lines (40 loc) · 2.46 KB

AesGcmStrict (.NET) NuGet

AesGcmStrict class:

  • Wraps AesGcm and enforces AesGcm Tag to be exactly 16 bytes. Use AesGcmStrict instead of AesGcm.
  • AesGcm allows truncated Tags: any AesGcm-provided Tag truncated to ex. 12 bytes will successfully decrypt.

Example of the problem:

Span<byte> plaintext = Encoding.UTF8.GetBytes("Hello World!");
Span<byte> key = new byte[32];
Span<byte> nonce = new byte[12];
Span<byte> ciphertext = new byte[plaintext.Length];
Span<byte> tag = new byte[16]; // generating a 16-byte Tag!

using var gcm = new AesGcm(key);

Console.WriteLine(Encoding.UTF8.GetString(plaintext));

gcm.Encrypt(nonce, plaintext, ciphertext, tag);
plaintext.Clear();
tag = tag.Slice(0, 12); // truncating the Tag to ex. 12 bytes
gcm.Decrypt(nonce, ciphertext, tag, plaintext); // decrypts successfully (PROBLEM)
Console.WriteLine(Encoding.UTF8.GetString(plaintext));

Most users of AesGcm might expect ~128 bits of Tag-security, but effectively get only ~96 bits at best.

How to fix with AesGcmStrict:

  1. Add the namespace: using SecurityDriven;
  2. Replace AesGcm with AesGcmStrict

Same example with AesGcmStrict:

// using SecurityDriven;
Span<byte> plaintext = Encoding.UTF8.GetBytes("Hello World!");
Span<byte> key = new byte[32];
Span<byte> nonce = new byte[12];
Span<byte> ciphertext = new byte[plaintext.Length];
Span<byte> tag = new byte[16]; // generating a 16-byte Tag!

using var gcm = new AesGcmStrict(key); // switching to AesGcmStrict

Console.WriteLine(Encoding.UTF8.GetString(plaintext));

gcm.Encrypt(nonce, plaintext, ciphertext, tag);
plaintext.Clear();
tag = tag.Slice(0, 12); // truncating the Tag to ex. 12 bytes
gcm.Decrypt(nonce, ciphertext, tag, plaintext); // throws ArgumentException (tag must be 16 bytes)
Console.WriteLine(Encoding.UTF8.GetString(plaintext));