当前位置:  开发笔记 > 编程语言 > 正文

"填充无效,无法删除"使用AesManaged

如何解决《"填充无效,无法删除"使用AesManaged》经验,为你挑选了2个好方法。

我正在尝试使用AesManaged进行简单的加密/解密,但在尝试关闭解密流时我一直遇到异常.这里的字符串被正确加密和解​​密,然后在Console.WriteLine输出正确的字符串后,我得到CryptographicException"Padding无效且无法删除".

有任何想法吗?

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);
  }
}

Cheeso.. 50

诀窍是使用MemoryStream.ToArray().我还更改了您的代码,以便CryptoStream在加密和解密时使用写入.并且您不需要CryptoStream.FlushFinalBlock()显式调用,因为您在using()语句中有它,并且将发生刷新Dispose().以下适用于我.

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实例的模式,并使用System.Security.Cryptography.Rfc2898DeriveBytes 从密码和salt派生密钥和IV.

另见:
- AesManaged



1> Cheeso..:

诀窍是使用MemoryStream.ToArray().我还更改了您的代码,以便CryptoStream在加密和解密时使用写入.并且您不需要CryptoStream.FlushFinalBlock()显式调用,因为您在using()语句中有它,并且将发生刷新Dispose().以下适用于我.

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实例的模式,并使用System.Security.Cryptography.Rfc2898DeriveBytes 从密码和salt派生密钥和IV.

另见:
- AesManaged


我有同样的问题,但使用RijndaelManaged(也是对称的)并且不知道发生了什么.事实证明,`MemoryStream.GetBuffer()`获得了*未刷新的*版本的数据,并且大多数最终的数据块都是null,这使我的填充变得混乱.`MemoryStream.ToArray()`获取真正的数组.非常感谢这个解决方案!
好好打电话给'Dispose`.我在处理CryptoStream之前调用了`ms.ToArray()`.在使用之外移动那条线为我固定它.

2> athina.bikak..:

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

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

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


我的问题是在设置密钥后设置KeySize,谢谢!
+1非常感谢你,如果可以,我会投票给你100次.我花了一天多时间试图弄清楚为什么我无法正确解密,结果发现我在代码中的密钥之后设置了密钥大小.
推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有