2011-02-28 41 views
0

我想使用AesManaged加密流(来自文件)。我可以在没有错误的情况下对文件进行加密,但解密时出现以下加密错误:解密流时填充无效

填充无效,不能删除 。

当处置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(); 
    } 
} 

为什么这个异常上来将是巨大的任何想法。由于

UPDATE

这里是AES创建对象,其中,需要注意的重点和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(); 
} 
+2

你能告诉你如何创建_myAes? – SimonJ 2011-02-28 23:47:26

+0

@SimonJ - 我在实例化对象的地方添加了片段。 – 2011-03-01 00:00:45

+0

这个错误可能是由很多事情造成的。最有可能的是你使用了错误的钥匙或IV。它也可能是由数据损坏引起的。 – 2011-03-01 00:43:46

回答

2

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

在丢弃它之前,您是否尝试在CryptoStream上拨打Flush?可能的话,如果它没有被刷新,那么它最终会尝试解密一个长度不对齐的缓冲区。

而另一注 - 我不知道这是否会解决你的问题,但是当你创建,以解密缓冲区CryptoStream,你不应该使用CryptoStreamMode.Read,而不是CryptoStreamMode.Write

+0

我认为你的最后一点可能应该是第一个:) – 2011-03-01 00:48:36

+0

我最初试过的方式使用了读模式,但我得到了同样的异常。 我试着在加密和解密的'CryptoStream'上调用'Flush'和'FlushFinalBlock',它仍然抛出同样的异常。 – 2011-03-01 02:00:26

+0

另外我应该指出,当我将其更改为'CryptoSteamMode.Read'时,它会在从流中读取而不是在处理它时抛出异常。 – 2011-03-01 02:04:11

0

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

+0

我很确定,当CryptoStream被丢弃时FlushFinalBlock被调用,但它应该明确完成恕我直言为清晰起见。 – 2011-03-01 00:40:06

+0

我试着在'Encrypt'方法中显式调用'FlushFinalBlock()',但我仍然得到相同的异常。 – 2011-03-01 02:05:43

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