Home > Software design >  .NET AES padding mode changes encrypted data size
.NET AES padding mode changes encrypted data size

Time:04-03

I don't necessarily have a problem, I am more curious. If I set the AES padding mode to PKCS7, and encrypt a byte[] of length 128, the output byte[] is length 144.

var input = new string('0', 128);
var inputBytes = Encoding.UTF8.GetBytes(input);

using var aes = Aes.Create();

Console.WriteLine(aes.BlockSize); // 128 (bits)

aes.Padding = PaddingMode.PKCS7;

using var encryptedMessageStream = new MemoryStream();
using (var cryptoStream = new CryptoStream(encryptedMessageStream, aes.CreateEncryptor(), CryptoStreamMode.Write, leaveOpen: true))
{
    cryptoStream.Write(inputBytes);
}

var encryptedBytes = encryptedMessageStream.ToArray(); // 144 length

If I change nothing expect switch the padding mode to None, then the encrypted bytes will have length 128 (same length as my input). So even though my input data has not changed, and the input length is evenly divisible by the AES block size (8 bytes), the padding mode is changing the final output. As far as my understanding goes, it shouldn't, because, my input length is evenly divisible by the AES block size. So why would PKCS7, and None be giving different output sizes?

When running both modes through decryption, I get the original message back just fine.

CodePudding user response:

PKCS padding requires that at least one byte of padding be added:

The total number of padding bytes is at least one, and is the number that is required in order to bring the data length up to a multiple of the cipher algorithm block size.

So, while you may feel that your round-block-size plaintext requires zero bytes, that's not a valid amount of padding because the minimum number is 1 byte. (The explanation of this is that otherwise it's impossible for the decipherer to differentiate between a round-block-size plaintext that happens to end in 0x01 and a one byte shorter plaintext that's padded with a single 0x01.)

  • Related