我正在尝试测试我的加密代码,并在处理 decrypt
时不断收到 CyrptographicException“填充无效且无法删除”。如果我尝试读取 decrypt
流的末尾,我会收到类似的错误,即使 CryptoStream.Read
文档表明这不应该成为问题。
一个简化的例子:
const int DATA_SET_SIZES = 102399;
byte[] iv,
key,
startingData = new byte[DATA_SET_SIZES],
encryptedData = new byte[((DATA_SET_SIZES - 1) / 16 + 2) * 16],
endingData = new byte[DATA_SET_SIZES];//[((DATA_SET_SIZES - 1) / 16 + 1) * 16];
Random rand = new Random();
rand.NextBytes(startingData); //Get test data.
using (Rijndael cryptAlg = Rijndael.Create())
{
cryptAlg.Mode = CipherMode.CBC;
cryptAlg.Padding = PaddingMode.ISO10126;
iv = cryptAlg.IV; //Use random IV during test.
key = cryptAlg.Key; //Use random Key during test.
using (CryptoStream encrypt = new CryptoStream(new MemoryStream(encryptedData), cryptAlg.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
encrypt.Write(startingData, 0, startingData.Length);
encrypt.FlushFinalBlock();
}
using (CryptoStream decrypt = new CryptoStream(new MemoryStream(encryptedData), cryptAlg.CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
int dataRecieved = decrypt.Read(endingData, 0, endingData.Length);
}
}
如果我执行以下操作之一,则异常消失:
- 在执行加密之后、创建
解密
之前更改cryptAlg.Padding = PaddingMode.None
。 - 更改
const int DATA_SET_SIZES = 102400
或 block 大小的任何其他倍数。 - 不要读取最后一个 block 中的任何数据。
我做错了什么或者 .NET 实现无法正确识别流的结尾吗?
另外,有谁知道为什么加密数据比存储加密数据所需的时间长 1 个 block ?该 block 中有什么?
最佳答案
您的encryptedData
缓冲区太大。输入 15 个字节,然后您将获得 32 个缓冲区 block 。由于您将完整的缓冲区提供给 MemoryStream
构造函数,因此它将读取到流的末尾。 block 解密永远不会失败,因此唯一会失败的是填充。最后一个 block 可能只包含零,因此解密的值是随机的,而不是匹配填充格式(大多数情况下)。
尝试:新字节[(DATA_SET_SIZES/16 +
1
) * 16]
关于c# - 部分读取最终 block 后的填充错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15171260/