为什么RijndaelManaged和AesCryptoServiceProvider会返回不同的结果?

时间:2009-06-05 18:33:42

标签: c# .net encryption rijndaelmanaged aescryptoserviceprovider

以下是我运行的示例。它具有相同的Mode,Padding,BlockSize,KeySize。我使用相同的init向量,密钥和数据。

使用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

使用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

以下是我用来生成这些结果的代码


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

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

更新:如果您尝试将CipherMode设置为CFB,则结果AesManaged将抛出CryptographicException(“指定的密码模式对此算法无效”)。我觉得AesCryptoServiceProvider也应该这样做,但它没有。看起来很有趣FIPS认证课程允许无效的密码模式。

3 个答案:

答案 0 :(得分:44)

微软的回应:

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

然而,  AesCryptoServiceProvider班级电话  Windows Crypto API,它使用  RSAENH.DLL,并已通过验证  CMVP中的NIST。虽然Rijndael  算法是NIST的赢家  竞争选择算法  那将成为AES,有一些  Rijndael和。之间的差异  官方AES。因此,  RijndaelManaged类和  AesCryptoServiceProvider班有  实施方面的微妙差异。

此外,RijndaelManaged课程  无法提供等价物  用AES实现。有  另一个在.net中实现的类  框架,AesManaged类。这个  刚刚被包裹的班级RijndaelManaged  具有固定块大小的类  迭代计数实现AES  标准。但是,它不支持  反馈大小,尤其是何时  模式设置为CFB或OFB,  CryptographicException将被抛出。

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

AesManaged ClassAesManaged.Mode Property

如果您想选择标准AES  你的安全算法  申请,我们建议使用  AesCryptoServiceProvider课程。如果你  想要混合RijndaelManged类  和AesCryptoServiceProvider上课  您的申请,我们建议使用CBC  你的模式而不是CFB模式  程序,自实施以来  两个班级的CBC模式都是  相同。

答案 1 :(得分:7)

我认为它与CipherMode.CFB有关。请参阅描述this postAesManaged

  

AesManaged实际上只是一个包装器   在Rinjdael附近管理一些代码   添加以确保您不这样做   设置算法以在a中运行   非AES兼容方式。例如,   AesManaged不允许你这样做   更改块大小。 (它也会   不允许使用CFB和OFB模式   因为那样的方式   RijndaelManaged与这些人合作   模式)。

请注意,如果您使用CipherMode.ECB或CipherMode.CBC,您将看到相同的结果。你需要CFB而不是CBC的原因是什么?

答案 2 :(得分:1)

来自this post的补充信息说:

基本上,如果您想将RijndaelManaged用作AES,您需要确保:
1)块大小设置为128位
2)您没有使用CFB模式,或者如果您的反馈大小也是128位

好的,太好了。我添加了mEncryptionType.FeedbackSize = 128;在上面的例子中,我得到了一个CryptographicExecption:

System.Security.Cryptography.CryptographicException was unhandled
  Message="Bad Data.\r\n"
  Source="System.Core"
  StackTrace:
       at System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandle key, KeyParameter parameter, Byte[] value)
       at System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandle key, KeyParameter parameter, Int32 value)
       at System.Security.Cryptography.CapiSymmetricAlgorithm.SetupKey(SafeCapiKeyHandle key, Byte[] iv, CipherMode cipherMode, Int32 feedbackSize)
       at System.Security.Cryptography.CapiSymmetricAlgorithm..ctor(Int32 blockSize, Int32 feedbackSize, SafeCspHandle provider, SafeCapiKeyHandle key, Byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, EncryptionMode encryptionMode)
       at System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor(SafeCapiKeyHandle key, Byte[] iv)
       at System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor(Byte[] key, Byte[] iv)
       at AESTest.Form1.Encrypt(Byte[] unencryptedData) in C:\Documents and Settings\nschoonmaker\My Documents\Visual Studio 2005\Projects\AESTest\AESTest\Form1.cs:line 79
       at AESTest.Form1..ctor() in C:\Documents and Settings\nschoonmaker\My Documents\Visual Studio 2005\Projects\AESTest\AESTest\Form1.cs:line 73
       at AESTest.Program.Main() in C:\Documents and Settings\nschoonmaker\My Documents\Visual Studio 2005\Projects\AESTest\AESTest\Program.cs:line 17

System.Core dll是否有什么问题不支持,或者我是否需要更改其他内容?

另外,如果我将FeedbackSize更改为8,它似乎工作!即使是CFB模式。所以我想我的下一个问题是,如何让128工作(希望这会结束这个问题)?