为什么RijndaelManaged的和AesCryptoServiceProvider返回不同的结果? [英] Why are RijndaelManaged and AesCryptoServiceProvider returning different results?

查看:483
本文介绍了为什么RijndaelManaged的和AesCryptoServiceProvider返回不同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我遇到的例子。它具有相同的模式,填充,BLOCKSIZE,密钥大小。我使用相同的init载体,密钥和数据。

Here is the example that I have run. It has the same Mode, Padding, BlockSize, KeySize. I am using the same init vector, key and data.

使用RijndaelManaged的产生的加密值: 0x8d,0x81,0x27,0xc6,0x3c,0xe2,0x53,0x2f,0x35,0x78,0x90,0xc2,0x2e,0x3b,0x8a,0x61, 0x41,0x47,0xd6,0xd0,0xff,0x92,0x72,0x3d,0xc6,0x16,0x2b,0xd8,0xb5,0xd9,0x12,0x85

Using the RijndaelManaged produces an encrypted value of: 0x8d,0x81,0x27,0xc6,0x3c,0xe2,0x53,0x2f,0x35,0x78,0x90,0xc2,0x2e,0x3b,0x8a,0x61, 0x41,0x47,0xd6,0xd0,0xff,0x92,0x72,0x3d,0xc6,0x16,0x2b,0xd8,0xb5,0xd9,0x12,0x85

使用AesCryptoServiceProvider产生的加密值: 0x8d,0x9f,0x6e,0x99,0xe9,0x54,0x8b,0x12,0xa9,0x88,0x1a,0x3D之间,0x65,0x23,0x9c,0x4e, 0x18,0x5a,0x89,0x31,0xf5,0x75,0xc5,0x9e,0X0D,0x43,0xe9,0x86,0xd4,0xf3,0x64,0x3a

Using the AesCryptoServiceProvider produces an encrypted value of: 0x8d,0x9f,0x6e,0x99,0xe9,0x54,0x8b,0x12,0xa9,0x88,0x1a,0x3d,0x65,0x23,0x9c,0x4e, 0x18,0x5a,0x89,0x31,0xf5,0x75,0xc5,0x9e,0x0d,0x43,0xe9,0x86,0xd4,0xf3,0x64,0x3a

下面是code我用来产生这些成果

Here is the code I used to generate these results



   public partial class AesTest
   {
      private SymmetricAlgorithm mEncryptionType;
      private byte[] mPrivateKey;
      private byte[] mInitializationVector;
      private byte[] mData;

      public AesTest()
      {
         mPrivateKey = new byte[32] 
         { 
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22,
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22, 
            0x22, 0x22, 0x22, 0x22
         };

         mInitializationVector = new byte[16]
         { 
            0x33, 0x33, 0x33, 0x33,
            0x33, 0x33, 0x33, 0x33,
            0x33, 0x33, 0x33, 0x33,
            0x33, 0x33, 0x33, 0x33
         };

         mData = new byte[16]
         {
            0x44, 0x44, 0x44, 0x44,
            0x44, 0x44, 0x44, 0x44,
            0x44, 0x44, 0x44, 0x44,
            0x44, 0x44, 0x44, 0x44
         };

         mEncryptionType = new RijndaelManaged();
         mEncryptionType.Mode = CipherMode.CFB;
         mEncryptionType.Padding = PaddingMode.PKCS7;
         mEncryptionType.BlockSize = 128;
         mEncryptionType.KeySize = 256;

         byte[] rij_encrypted_data = Encrypt(mData);

         mEncryptionType = new AesCryptoServiceProvider();
         mEncryptionType.Mode = CipherMode.CFB;
         mEncryptionType.Padding = PaddingMode.PKCS7;
         mEncryptionType.BlockSize = 128;
         mEncryptionType.KeySize = 256;

         byte[] aes_encrypted_data = Encrypt(mData);
      }

      public virtual byte[] Encrypt(byte[] unencryptedData)
      {
         return TransformData(unencryptedData, mEncryptionType.CreateEncryptor(mPrivateKey, mInitializationVector));
      }

      private byte[] TransformData(byte[] dataToTransform, ICryptoTransform cryptoTransform)
      {
         byte[] result = new byte[0];
         if (dataToTransform != null && cryptoTransform != null && dataToTransform.Length > 0)
         {
            // Create the memory stream to store the results
            MemoryStream mem_stream = new MemoryStream();
            // Create the crypto stream to do the transformation
            CryptoStream crypto_stream = new CryptoStream(mem_stream, cryptoTransform, CryptoStreamMode.Write);
            // bytes are transformed on a write
            crypto_stream.Write(dataToTransform, 0, dataToTransform.Length);
            // Flush the final block
            crypto_stream.FlushFinalBlock();
            // Convert the transformed memory stream back to a byte array
            result = mem_stream.ToArray();
            // Close the streams
            mem_stream.Close();
            crypto_stream.Close();
         }
         return result;
      }
   }

我想我只是想知道如果我错过了什么。

I guess I'm just wondering if I missed something.

更新:原来,<一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx">AesManaged将抛出一个CryptographicException(指定的加密模式是不适用于这种算法),如果你尝试设置CipherMode为CFB。我觉得<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aescryptoserviceprovider.aspx">AesCryptoServiceProvider应该做的一样,但它没有。似乎滑稽的FIPS认证的类允许无效的密码模式。

Update: Turns out that AesManaged will throw a CryptographicException ("The specified cipher mode is not valid for this algorithm") if you try and set the CipherMode to CFB. I feel that the AesCryptoServiceProvider should do that same, but it doesnt. Seems funny that the FIPS Certified class allows invalid cipher modes.

推荐答案

微软回应:

RijndaelManaged的类   AesCryptoServiceProvider 类有两个  不同的实现。   RijndaelManaged的类是一种  实现Rijndael算法的  在.NET框架中,这是不  NIST(美国国家下验证  标准和技术研究所)  加密模块验证  计划(CMVP)。

RijndaelManaged class and AesCryptoServiceProvider class are two different implementations. RijndaelManaged class is a kind of implementation of Rijndael algorithm in .net framework, which was not validated under NIST (National Institute of Standards and Technology) Cryptographic Module Validation Program (CMVP).

不过,   AesCryptoServiceProvider 类电话  在Windows加密API,它使用  为Rsaenh.dll,并已通过验证  NIST的CMVP。尽管Rijndael算法  算法是NIST的赢家  竞争选择算法  这将成为AES,也有一些  Rijndael算法之间的差异  官方AES。因此,  RijndaelManaged类和   AesCryptoServiceProvider 类有  实施细微的差别。

However, AesCryptoServiceProvider class calls the Windows Crypto API, which uses RSAENH.DLL, and has been validated by NIST in CMVP. Although Rijndael algorithm was the winner of the NIST competition to select the algorithm that would become AES, there are some differences between Rijndael and official AES. Therefore, RijndaelManaged class and AesCryptoServiceProvider class have subtle differences on implementation.

此外, RijndaelManaged的类  不能提供一个等效  实现与AES。有  在.NET中实现的另一个类  框架, AesManaged 类。本  班刚刚结束 RijndaelManaged的  类与固定的块大小和  迭代次数达到了AES  标准。然而,它不支持  反馈大小,特别是,当  所述模式被设置为CFB或OFB,所述   CryptographicException 将被抛出。

In addition, RijndaelManaged class cannot provide an equivalent implementation with AES. There is another class implemented in .net framework, AesManaged class. This class just wrapped RijndaelManaged class with a fixed block size and iteration count to achieve the AES standard. However, it does not support the feedback size, especially, when the mode is set as CFB or OFB, the CryptographicException will be thrown.

有关详细信息,请参考  以下MSDN文档。

For more information, please refer to the following MSDN documents.

<一个href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx">AesManaged类和<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.mode.aspx">AesManaged.Mode物业

如果你想拿起标准AES作为  在安全算法的  应用程序,我们建议使用   AesCryptoServiceProvider 类。如果你  想混 RijndaelManged 类  和 AesCryptoServiceProvider 类  您的应用程序,我们建议使用CBC  模式而不是在CFB模式下  方案中,由于执行  CBC模式中的两个类是  一样的。

If you want to pick up standard AES as security algorithm in your application, we recommend using the AesCryptoServiceProvider class. If you want to mix the RijndaelManged class and AesCryptoServiceProvider class in your application, we suggest using CBC mode instead of CFB mode in your program, since the implementation of the CBC mode in both classes is the same.

这篇关于为什么RijndaelManaged的和AesCryptoServiceProvider返回不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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