33

これが私が実行した例です。Mode、Padding、BlockSize、KeySize は同じです。同じ初期化ベクトル、キー、およびデータを使用しています。

RijndaelManaged を使用すると、次の暗号化された値が生成されます。 ,0x92,0x72,0x3d,0xc6,0x16,0x2b,0xd8,0xb5,0xd9,0x12,0x85

AesCryptoServiceProvider を使用すると、次の暗号化された値が生成されます。 ,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 認定クラスが無効な暗号モードを許可しているのはおかしいようです。

4

3 に答える 3

46

マイクロソフトからの応答:

RijndaelManagedクラスと AesCryptoServiceProviderクラスは 2 つの異なる実装です。 RijndaelManagedクラスは、.net フレームワークでの Rijndael アルゴリズムの一種の実装であり、NIST (米国国立標準技術研究所) 暗号化モジュール検証プログラム (CMVP) で検証されていません。

ただし、 AesCryptoServiceProviderクラスは RSAENH.DLL を使用する Windows Crypto API を呼び出し、CMVP で NIST によって検証されています。Rijndael アルゴリズムは、AES になるアルゴリズムを選択するための NIST コンペティションの勝者でしたが、Rijndael と公式の AES にはいくつかの違いがあります。したがって、RijndaelManaged クラスと AesCryptoServiceProviderクラスには、実装上の微妙な違いがあります。

さらに、RijndaelManagedクラスは AES と同等の実装を提供できません。.net フレームワークに実装されている別のクラス、AesManagedクラスがあります。RijndaelManaged このクラスは、AES 標準を達成するために固定ブロック サイズと反復回数でクラスをラップしただけです。ただし、フィードバック サイズはサポートされていません。特に、モードが CFB または OFB に設定されている場合は、 CryptographicExceptionがスローされます。

詳細については、次の MSDN ドキュメントを参照してください。

AesManaged クラスAesManaged.Mode プロパティ

アプリケーションのセキュリティ アルゴリズムとして標準の AES を使用する場合は、 AesCryptoServiceProviderクラスを使用することをお勧めします。RijndaelMangedアプリケーションでクラスとクラスを混在させたい場合AesCryptoServiceProviderは、プログラムで CFB モードではなく CBC モードを使用することをお勧めします。これは、両方のクラスでの CBC モードの実装が同じであるためです。

于 2011-02-01T14:44:07.640 に答える
7

CipherMode.CFB と関係があると思います。AesManagedについて説明しているこの投稿を参照してください。

AesManaged は、実際には RinjdaelManaged の単なるラッパーであり、AES と互換性のない方法で動作するようにアルゴリズムをセットアップしないようにするためのコードが追加されています。たとえば、AesManaged ではブロック サイズを変更できません。(RijndaelManaged がこれらのモードで動作する方法のため、CFB および OFB モードの使用も禁止されます)。

CipherMode.ECB または CipherMode.CBC を使用すると、同じ結果が得られることに注意してください。CBCではなくCFBが必要な理由は何ですか?

于 2009-06-05T18:46:43.443 に答える
1

この投稿からの追加情報は言う:

基本的に、RijndaelManagedをAESとして使用する場合は、次のことを確認する必要があります
。1)ブロックサイズが128ビットに設定されて
いる2)CFBモードを使用していないか、フィードバックサイズも128ビットである

わかりました、すばらしい。mEncryptionType.FeedbackSize=128を追加しました。上記の例では、CryptographicExecptionを取得します。

System.Security.Cryptography.CryptographicExceptionは処理されませんでした
  Message="不正なデータ。\r\ n"
  Source = "System.Core"
  スタックトレース:
       System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandleキー、KeyParameterパラメーター、Byte []値)
       System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandleキー、KeyParameterパラメーター、Int32値)
       System.Security.Cryptography.CapiSymmetricAlgorithm.SetupKey(SafeCapiKeyHandle key、Byte [] iv、CipherMode cipherMode、Int32 FeedbackSize)で
       System.Security.Cryptography.CapiSymmetricAlgorithm..ctor(Int32 blockSize、Int32 FeedbackSize、SafeCspHandleプロバイダー、SafeCapiKeyHandleキー、Byte [] iv、CipherMode cipherMode、PaddingMode paddingMode、EncryptionMode EncryptionMode)
       System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor(SafeCapiKeyHandle key、Byte [] iv)で
       System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor(Byte []キー、Byte [] iv)で
       C:\ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Form1.cs:line79のAESTest.Form1.Encrypt(Byte [] unencryptedData)
       C:\ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Form1.cs:line73のAESTest.Form1..ctor()
       C:\ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Program.cs:line 17のAESTest.Program.Main()

これをサポートしないSystem.Coredllに何か問題がありますか、それとも他の何かを変更する必要がありますか?

ちなみに、両方のFeedbackSizeを8に変更すると、機能するようです。CFBモードでも。だから私の次の質問は、どうすれば128を機能させることができるかということだと思います(そしてうまくいけば、これでこの質問に終止符が打たれるでしょう)?

于 2009-06-08T23:05:47.187 に答える