2017-06-19 94 views
-2

我实现下面的方法:AES加密

AesCryptoServiceProvider provider = new AesCryptoServiceProvider(); 
provider.Mode = CipherMode.ECB; 
provider.KeySize = 128; 
provider.BlockSize = 128; 
provider.Key = key; 
provider.Padding = PaddingMode.PKCS7; 
transform = provider.CreateDecryptor(); 

public static byte[] AESDecrypt(byte[] data, ICryptoTransform transform) 
    { 
     using (MemoryStream stream = new MemoryStream(data)) 
     using (CryptoStream cstream = new CryptoStream(stream, transform, CryptoStreamMode.Read)) 
     using (MemoryStream output = new MemoryStream()) 
     { 
      byte[] buffer = new byte[4000]; 
      int r; 
      while ((r = cstream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       output.Write(buffer, 0, r); 
      } 
      stream.Close(); 
      return output.ToArray(); 
     } 
    } 

我使用这种方法来解密的16个字节的块的序列,所述transform参数在开始时初始化一次

我的问题是突然该方法开始产生奇怪的输出,16个字节的块被解密为27个字节!!!!,有时16个字节被错误解密为16个字节,但是当我重新启动应用程序时,相同的数据产生正确结果,做转变何是否有这种情况发生?我做了什么错事,使得16个字节块被解密为27个字节。

任何帮助表示赞赏

`编辑:

有人可以确认这是相同的错误: Reuse ICryptoTransform objects

编辑2:

东西添加到正确答案:

看来ICryptoTransform不是线程安全的,所以从两个线程调用上述方法同时可能会导致麻烦,我通过为每个正在使用方法的线程创建ICrypteTransform对象来解决此问题。

+0

不,它是一样的,但是我发现这个https://stackoverflow.com/questions/43593495/reuse-icryptotransform-objects/43598850 – ammcom

+0

反正我告诉你,16个字节被解密27个字节,什么使它与我的约会相关??????您的评论是不适合的 – ammcom

回答

3

当您打算关闭cstream时,您正在关闭stream

由于在读出数据之前您没有关闭cstream,因此永远不会调用TransformFinalBlock

你最好使用Stream.CopyTo,并且让你的输出流比CryptoStream拥有更长的生命周期。

public static byte[] AESDecrypt(byte[] data, ICryptoTransform transform) 
{ 
    using (MemoryStream output = new MemoryStream()) 
    { 
     using (MemoryStream stream = new MemoryStream(data)) 
     using (CryptoStream cstream = new CryptoStream(stream, transform, CryptoStreamMode.Read)) 
     { 
      cstream.CopyTo(output); 
     } 

     return output.ToArray(); 
    } 
} 
+0

谢谢你的信息,但在知道解密不涉及调用TransferFinalBlock因为所有的输入总是除以16(这是填充的好处)。任何方式感谢您的注意 – ammcom

+2

@ammcom TransformFinalBlock负责删除任何填充,以及重置ICryptoTransform。确保它被调用是非常重要的,否则你的输出变得非常不稳定。 – bartonjs