首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用AesManaged“填充无效,无法移除”

使用AesManaged“填充无效,无法移除”
EN

Stack Overflow用户
提问于 2009-03-02 22:03:23
回答 6查看 73.5K关注 0票数 39

我正在尝试使用AesManaged进行简单的加密/解密,但在尝试关闭解密流时总是出现异常。这里的字符串得到了正确的加密和解密,然后在Console.WriteLine打印正确的字符串后,我得到了CryptographicException“填充是无效的,无法被删除”。

有什么想法吗?

代码语言:javascript
运行
复制
MemoryStream ms = new MemoryStream();
byte[] rawPlaintext = Encoding.Unicode.GetBytes("This is annoying!");

using (Aes aes = new AesManaged())
{
  aes.Padding = PaddingMode.PKCS7;
  aes.Key = new byte[128/8];
  aes.IV = new byte[128/8];

  using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(),
                                            CryptoStreamMode.Write))
  {
    cs.Write(rawPlaintext, 0, rawPlaintext.Length);
    cs.FlushFinalBlock();
  }

  ms = new MemoryStream(ms.GetBuffer());
  using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(),
                                            CryptoStreamMode.Read))
  {
    byte[] rawData = new byte[rawPlaintext.Length];
    int len = cs.Read(rawData, 0, rawPlaintext.Length);
    string s = Encoding.Unicode.GetString(rawData);
    Console.WriteLine(s);
  }
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-03-02 23:16:00

诀窍是使用MemoryStream.ToArray()。我还更改了您的代码,使其在加密和解密时都使用CryptoStream编写。而且您不需要显式地调用CryptoStream.FlushFinalBlock(),因为您在using()语句中拥有它,并且刷新将在Dispose()上发生。下面的方法对我很有效。

代码语言:javascript
运行
复制
byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!");

using (Aes aes = new AesManaged())
{
    aes.Padding = PaddingMode.PKCS7;
    aes.KeySize = 128;          // in bits
    aes.Key = new byte[128/8];  // 16 bytes for 128 bit encryption
    aes.IV = new byte[128/8];   // AES needs a 16-byte IV
    // Should set Key and IV here.  Good approach: derive them from 
    // a password via Cryptography.Rfc2898DeriveBytes 
    byte[] cipherText= null;
    byte[] plainText= null;

    using (MemoryStream ms = new MemoryStream())
    {
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
        {
            cs.Write(rawPlaintext, 0, rawPlaintext.Length);
        }

        cipherText= ms.ToArray();
    }


    using (MemoryStream ms = new MemoryStream())
    {
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
        {
            cs.Write(cipherText, 0, cipherText.Length);
        }

        plainText = ms.ToArray();
    }
    string s = System.Text.Encoding.Unicode.GetString(plainText);
    Console.WriteLine(s);
}

此外,我猜您知道您需要显式设置AesManaged实例的Mode,并使用System.Security.Cryptography.Rfc2898DeriveBytes从密码和盐派生密钥和IV。

另请参阅:

票数 62
EN

Stack Overflow用户

发布于 2010-12-01 18:51:13

此异常可能是由多个加密参数中的任何一个不匹配引起的。

我使用Security.Cryptography.Debug接口跟踪加密/解密方法中使用的所有参数。

最后,我发现我的问题是我在设置Key之后设置了KeySize属性,导致类重新生成一个随机密钥,而不是使用我最初设置的密钥。

票数 30
EN

Stack Overflow用户

发布于 2019-06-12 09:39:50

为了它的价值,我会记录下我所面对的。在CryptoStream关闭之前,我正在尝试读取加密器内存流。我太天真了,我浪费了一天的时间调试它。

代码语言:javascript
运行
复制
    public static byte[] Encrypt(byte[] buffer, byte[] sessionKey, out byte[] iv)
    {
        byte[] encrypted;
        iv = null;
        using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider { Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 })
        {
            aesAlg.Key = sessionKey;
            iv = aesAlg.IV;
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(sessionKey, iv);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    csEncrypt.Write(buffer, 0, buffer.Length);
                    
                    //This was not closing the cryptostream and only worked if I called FlushFinalBlock()
                    //encrypted = msEncrypt.ToArray(); 
                }

                encrypted = msEncrypt.ToArray();

                return encrypted;
            }
        }
    }

在cypto流关闭后移动读取的加密器内存流解决了这个问题。正如Cheeso提到的。如果使用using块,则不需要调用FlushFinalBlock()

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/604210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档