我在C#中设置了一个简单的对称AES-en / decryption,但是我遇到填充问题。根据{{3}},PKCS#7的填充字节应该是0x07
,但在我的情况下,它只是零字节(0x00
)。
这怎么可能?看起来似乎没有在.NET中正确实现......
这是我的代码:
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!)
答案 0 :(得分:8)
解密器正在正确删除加密器应用的填充,因此输出中的零字节只是原始plainData
数组中未触摸的字节。 cryptoStream.Read(...)
调用返回一个整数,指示读取的字节数(在本例中为1
),您应该使用它来确定输出数组中有多少字节是有效数据。
如果由于某种原因您有兴趣查看填充字节,可以在执行加密后设置aes.Padding = PaddingMode.None;
,但之前创建解密器。然后,您会发现cryptoStream.Read(...)
返回16
,plainData
有0xff
作为其第一个字节,后跟15个字节的0x0f
填充(不知道为什么你的问题表明你期待0x07
。)
答案 1 :(得分:0)
对于PKCS7模式,它应该是blocksize - contentsize
,即你的情况下16-1 = 15。您的错误是您在解密后期望它,但填充在加密之前发生在内部。根据选择的模式,无法保证plainData
将包含填充字节。