解密流时填充无效

时间:2011-02-28 23:34:48

标签: c# encryption aes

我正在尝试使用AesManaged加密流(来自文件)。我可以毫无错误地加密文件,但在解密时我得到以下CryptographicException:

  

填充无效,不可以   除去。

处理CryptoStream时会引发异常。我使用以下内容来加密输入数据:

public byte[] Encrypt(Stream plain)
{
    // Create a decrytor to perform the stream transform.
    using( var msEncrypt = new MemoryStream() )
    {
        using (ICryptoTransform encryptor = _myAes.CreateEncryptor(_myAes.Key, _myAes.IV))
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        using (BinaryWriter swEncrypt = new BinaryWriter(csEncrypt))
        {
            int buf_size = 32768;
            byte[] buffer = new byte[buf_size];
            int read = 0;
            while ((read = plain.Read(buffer, 0, buf_size)) > 0)
            {
                swEncrypt.Write(buffer, 0, read);
            }
        }

        return msEncrypt.ToArray();
    }
}

这是解密数据:

public byte[] Decrypt(Stream cipherText)
{

    using (MemoryStream ms = new MemoryStream())
    {
        // Create a decrytor to perform the stream transform.
        using (ICryptoTransform decryptor = _myAes.CreateDecryptor(_myAes.Key, _myAes.IV))
        using (CryptoStream csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
        using (BinaryWriter swDecrypt = new BinaryWriter(csDecrypt))
        {
            int buf_size = 32768;
            byte[] buffer = new byte[buf_size];
            int read = 0;
            while ((read = cipherText.Read(buffer, 0, buf_size)) > 0)
            {
                swDecrypt.Write(buffer, 0, read);
            }
        }

        return ms.ToArray();
    }
}

关于为什么会出现此异常的任何想法都会很棒。感谢

更新

这里是Aes对象的创建位置,注意Key和IV只是暂时设置为它们的当前值,它不是将要使用的真正键:

private Crypto()
{
    _myAes = new AesManaged();
    _myAes.Padding = PaddingMode.PKCS7;
    _myAes.KeySize = 128;
    _myAes.Key = Enumerable.Repeat((byte)'B', 128 / 8).ToArray();
    _myAes.IV = Enumerable.Repeat((byte)'C', 128 / 8).ToArray();
}

3 个答案:

答案 0 :(得分:2)

过去,当我尝试解密长度不是16字节倍数的缓冲区时,我遇到了这个异常。

您在Flush处理CryptoStream之前是否尝试过它?可能,如果没有刷新,那么它最终会尝试解密具有不对齐长度的缓冲区。

另一个注意事项 - 我不知道这是否会解决您的问题,但是当您创建CryptoStream以解密缓冲区时,您不应该使用CryptoStreamMode.Read而不是{ {1}}?

答案 1 :(得分:0)

确保在写入方面干净地完成CryptoStream。您可能需要调用FlushFinalBlock()以确保写入流末尾填充 - 否则,您可能最终会丢失流的最后一个块,这将导致无效的填充异常。

答案 2 :(得分:0)

我不知道4年后发布的东西是否仍然相关,但是你应该尝试将填充设置为无。我遇到了与3DES相同的问题,问题解决了(但要确保要解密的数据长度是正确的......)

private Crypto()
{
    _myAes = new AesManaged();
    _myAes.Padding = PaddingMode.none; //rather than _myAes.Padding = PaddingMode.PKCS7;
    _myAes.KeySize = 128;
    _myAes.Key = Enumerable.Repeat((byte)'B', 128 / 8).ToArray();
    _myAes.IV = Enumerable.Repeat((byte)'C', 128 / 8).ToArray();
}