c# - 部分读取最终 block 后的填充错误

标签 c# cryptography rijndael

我正在尝试测试我的加密代码,并在处理 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/

相关文章:

C#串口精准时间戳

c# - asp.net母版页执行的顺序

javascript - 根据密码在javascript中生成RSA key 对

java - Rijndael 256 加密 : Java and . NET 不匹配

java - 解密 C# RIJNDAEL 编码的文本

c# - DeflateStream/GZipStream 到 CryptoStream,反之亦然

c# - 在 MonoDevelop 中,如何将应用程序输出设置为固定宽度字体?

c# - SqlConnection、连接池和工作单元的设计模式

security - 临时存储敏感数据

java - 发送带有密文的 IV