"填充是无效的,不能删除"使用AesManaged [英] "Padding is invalid and cannot be removed" using AesManaged

查看:179
本文介绍了"填充是无效的,不能删除"使用AesManaged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让简单的加密/解密与AesManaged工作,但我一直试图关闭解密流时得到一个例外。这里的字符串被加密并正确解密,然后我得到的CryptographicException填充是无效的,不能被删除后Console.WriteLine打印正确的字符串。

任何想法?

 的MemoryStream毫秒​​=新的MemoryStream();
byte []的rawPlaintext = Encoding.Uni code.GetBytes(这是烦人!);

使用(AES公司AES =新AesManaged())
{
  aes.Padding = PaddingMode.PKCS7;
  aes.Key =新的字节[八分之一百二十八]
  aes.IV =新的字节[八分之一百二十八]

  使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateEncryptor()
                                            CryptoStreamMode.Write))
  {
    cs.Write(rawPlaintext,0,rawPlaintext.Length);
    cs.FlushFinalBlock();
  }

  MS =新的MemoryStream(ms.GetBuffer());
  使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateDecryptor()
                                            CryptoStreamMode.Read))
  {
    byte []的RAWDATA =新的字节[rawPlaintext.Length]
    INT LEN = cs.Read(RAWDATA,0,rawPlaintext.Length);
    字符串s = Encoding.Uni code.GetString(RAWDATA);
    Console.WriteLine(多个);
  }
}
 

解决方案

的技巧是使用 MemoryStream.ToArray()。 我也改变了你的code,以便它使用了的CryptoStream 来写,在加密和解密。而你并不需要调用 CryptoStream.FlushFinalBlock()明确,因为你必须在一个使用()声明中,并刷新将发生在的Dispose()。以下为我工作。

 字节[] rawPlaintext = System.Text.Encoding.Uni code.GetBytes(这一切清楚了吧!);

使用(AES公司AES =新AesManaged())
{
    aes.Padding = PaddingMode.PKCS7;
    aes.KeySize = 128; //位数
    aes.Key =新的字节[八分之一百二十八] // 16字节128位加密
    aes.IV =新的字节[八分之一百二十八] // AES需要16个字节的第四
    //应该设置密钥和IV在这里。好办法:从得到他们
    //通过Cryptography.Rfc2898DeriveBytes密码
    byte []的密文= NULL;
    byte []的明文= NULL;

    使用(MemoryStream的毫秒=新的MemoryStream())
    {
        使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateEncryptor(),CryptoStreamMode.Write))
        {
            cs.Write(rawPlaintext,0,rawPlaintext.Length);
        }

        密文= ms.ToArray();
    }


    使用(MemoryStream的毫秒=新的MemoryStream())
    {
        使用(CryptoStream的CS =新的CryptoStream(MS,aes.CreateDecryptor(),CryptoStreamMode.Write))
        {
            cs.Write(密文,0,cipherText.Length);
        }

        明文= ms.ToArray();
    }
    字符串s = System.Text.Encoding.Uni code.GetString(明文);
    Console.WriteLine(多个);
}
 

另外,我想你知道你将要明确设置<一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.mode.aspx">Mode在AesManaged实例,并使用<一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx">System.Security.Cryptography.Rfc2898DeriveBytes导出密钥和IV从一个密码和盐

另见:
- <一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx">AesManaged

I'm trying to get simple encryption/decryption working with AesManaged, but I keep getting an exception when trying to close the decryption stream. The string here gets encrypted and decrypted correctly, and then I get the CryptographicException "Padding was invalid and cannot be removed" after Console.WriteLine prints the correct string.

Any ideas?

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

解决方案

The trick is to use MemoryStream.ToArray(). I also changed your code so that it uses the CryptoStream to Write, in both encrypting and decrypting. And you don't need to call CryptoStream.FlushFinalBlock() explicitly, because you have it in a using() statement, and that flush will happen on Dispose(). The following works for me.

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

Also, I guess you know you will want to explicitly set the Mode of the AesManaged instance, and use System.Security.Cryptography.Rfc2898DeriveBytes to derive the Key and IV from a password and salt.

see also:
- AesManaged

这篇关于&QUOT;填充是无效的,不能删除&QUOT;使用AesManaged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆