Pergunta

I have set up a simple symmetric AES-en/decryption in C#, but I'm having problems with the padding. According to MSDN, the padding bytes for PKCS #7 are supposed to be 0x07, but in my case it's just zero-bytes (0x00).

How is this possible? It almost seems as if this was not correctly implemented in .NET...

Here is my code:

Aes aes = new AesManaged();
aes.Key = new byte[] { /* ...  */ };
aes.IV = new byte[] { /* ... */ };
// Debugging shows:
// aes.Padding = PaddingMode.PKCS7

// the data to encrypt (1 byte only, to demonstrate padding)
byte[] plainData = new byte[1] { 0xFF };
byte[] encData;

// (encrypt)
using (MemoryStream encStream = new MemoryStream())
{
    using (CryptoStream cryptoStream = new CryptoStream(encStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
    {
        cryptoStream.Write(plainData, 0, plainData.Length);
    }
    encData = encStream.ToArray();
}

// (new length is 16 bytes (128 bits), incl. padding)
plainData = new byte[16];

// (decrypt)
using (MemoryStream decrStream = new MemoryStream(encData))
{
    using (CryptoStream cryptoStream = new CryptoStream(decrStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
    {
        cryptoStream.Read(plainData, 0, plainData.Length);
    }
}

// output:
// 16 bytes,
// 1st byte = 0xFF,
// other 15 bytes = 0x00 (instead of 0x07!)
Foi útil?

Solução

The decryptor is correctly removing the padding that was applied by the encryptor, thus the zero bytes in your output are simply the un-touched bytes in the original plainData array. The cryptoStream.Read(...) call returns an integer indicating the number of bytes that were read (1 in this case), which you should be using to determine how many bytes in the output array are valid data.

If for whatever reason you are interested in seeing the padding bytes, you can set aes.Padding = PaddingMode.None; after the encryption is performed, but before you create the decryptor. You will then find that cryptoStream.Read(...) returns 16, and plainData has 0xff as its first byte, followed by 15 bytes of 0x0f padding (not sure why your question indicates you were expecting 0x07 though).

Outras dicas

For PKCS7 mode it should be blocksize - contentsize, i.e. 16 - 1 = 15 in your case. Your mistake is that you expect it after decryption but padding happens internally before encryption. There are no guarantees that plainData will contain padded bytes according to mode choosen.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top