Pertanyaan Mengapa RijndaelManaged dan AesCryptoServiceProvider mengembalikan hasil yang berbeda?


Inilah contoh yang saya jalankan. Ini memiliki Mode yang sama, Padding, BlockSize, KeySize. Saya menggunakan vektor init yang sama, kunci dan data.

Menggunakan RijndaelManaged menghasilkan nilai terenkripsi dari: 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

Menggunakan AesCryptoServiceProvider menghasilkan nilai terenkripsi dari: 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

Berikut adalah kode yang saya gunakan untuk menghasilkan hasil ini


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

Kurasa aku hanya ingin tahu apakah aku melewatkan sesuatu.

 Memperbarui:  Ternyata itu Aes dikelola akan melempar CryptographicException ("Mode cipher yang ditentukan tidak berlaku untuk algoritma ini") jika Anda mencoba dan mengatur CipherMode ke CFB. Saya merasa bahwa itu AesCryptoServiceProvider harus melakukan hal yang sama, tetapi tidak. Tampaknya lucu bahwa kelas Bersertifikat FIPS memungkinkan mode cipher yang tidak valid.


32
2018-06-05 18:33


asal


Jawaban:


Tanggapan dari Microsoft:

RijndaelManaged kelas dan   AesCryptoServiceProvider kelas dua  implementasi yang berbeda.   RijndaelManaged kelas adalah sejenis  implementasi algoritma Rijndael  di .net framework, yang tidak  divalidasi di bawah NIST (Nasional  Institut Standar dan Teknologi)  Validasi Modul Cryptographic  Program (CMVP).

Namun,   AesCryptoServiceProvider panggilan kelas  Windows Crypto API, yang menggunakan  RSAENH.DLL, dan telah divalidasi oleh  NIST di CMVP. Meskipun Rijndael  algoritma adalah pemenang NIST  persaingan untuk memilih algoritma  itu akan menjadi AES, ada beberapa  perbedaan antara Rijndael dan  AES resmi. Karena itu,  Rijndael Kelas yang dikelola dan   AesCryptoServiceProvider kelas miliki  perbedaan halus pada implementasi.

Sebagai tambahan, RijndaelManaged kelas  tidak dapat memberikan yang setara  implementasi dengan AES. Ada  kelas lain diimplementasikan dalam .net  kerangka, AesManaged kelas. Ini  kelas baru saja dibungkus RijndaelManaged  kelas dengan ukuran blok tetap dan  jumlah iterasi untuk mencapai AES  standar. Namun, itu tidak mendukung  ukuran umpan balik, khususnya, kapan  mode diatur sebagai CFB atau OFB, the   CryptographicException akan dilemparkan.

Untuk informasi lebih lanjut, silakan merujuk ke  dokumen MSDN berikut.

AesManaged Class        dan AesManaged.Mode Properti 

Jika Anda ingin mengambil AES standar sebagai  algoritma keamanan dalam  aplikasi, kami menyarankan menggunakan   AesCryptoServiceProvider kelas. Jika kamu  ingin mencampur RijndaelManged kelas  dan AesCryptoServiceProvider kelas masuk  aplikasi Anda, kami sarankan menggunakan CBC  mode bukan mode CFB di Anda  program, sejak implementasi  Modus CBC di kedua kelas adalah  sama.


40
2018-02-01 14:44



Saya pikir itu ada hubungannya dengan CipherMode.CFB. Lihat posting ini menggambarkan Aes dikelola:

AesManaged sebenarnya hanyalah pembungkus   sekitar Rinjdael dikelola dengan beberapa kode   ditambahkan untuk memastikan bahwa Anda tidak   setup algoritma untuk beroperasi dalam   cara yang tidak kompatibel dengan AES. Contohnya,   AesManaged tidak memungkinkan Anda melakukannya   ubah ukuran blok. (Ini juga akan terjadi   tidak mengizinkan penggunaan mode CFB dan OFB   karena cara itu   Rijndael dikelola bekerja dengan mereka   mode).

Perhatikan bahwa jika Anda menggunakan CipherMode.ECB atau CipherMode.CBC, Anda akan melihat hasil yang identik. Ada alasan mengapa Anda membutuhkan CFB dan bukan CBC?


6
2018-06-05 18:46



Informasi tambahan dari posting ini mengatakan:

Pada dasarnya, jika Anda ingin menggunakan Rijndael dikelola sebagai AES Anda harus memastikan bahwa:
1) Ukuran blok diatur ke 128 bit
2) Anda tidak menggunakan mode CFB, atau jika Anda ukuran umpan balik juga 128 bit

OK bagus. Saya menambahkan mEncryptionType.FeedbackSize = 128; ke contoh di atas dan saya mendapatkan CryptographicExecption:

System.Security.Cryptography.CryptographicException tidak ditangani
  Pesan = "Data Buruk. \ R \ n"
  Sumber = "System.Core"
  StackTrace:
       di System.Security.Cryptography.CapiNative.SetKeyParameter (SafeCapiKeyHandle key, parameter KeyParameter, Byte [] value)
       di System.Security.Cryptography.CapiNative.SetKeyParameter (kunci SafeCapiKeyHandle, parameter KeyParameter, nilai Int32)
       di System.Security.Cryptography.CapiSymmetricAlgorithm.SetupKey (SafeCapiKeyHandle key, Byte [] iv, CipherMode cipherMode, Int32 feedbackSize)
       di System.Security.Cryptography.CapiSymmetricAlgorithm..ctor (blok Int32Ukuran, Int32 feedbackSize, penyedia SafeCspHandle, kunci SafeCapiKeyHandle, Byte [] iv, CipherMode cipherMode, PaddingMode paddingMode, EncryptionMode encryptionMode)
       di System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor (SafeCapiKeyHandle key, Byte [] iv)
       di System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor (Byte [], Byte [] iv)
       di AESTest.Form1.Encrypt (Byte [] unencryptedData) di C: \ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Form1.cs: baris 79
       di AESTest.Form1..ctor () di C: \ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Form1.cs: line 73
       di AESTest.Program.Main () di C: \ Documents and Settings \ nschoonmaker \ My Documents \ Visual Studio 2005 \ Projects \ AESTest \ AESTest \ Program.cs: baris 17

Apakah ada yang salah dengan dll System.Core yang tidak akan mendukung ini, atau apakah saya perlu mengubah sesuatu yang lain?

Di samping catatan, jika saya mengubah FeedbackSize menjadi 8 untuk keduanya, tampaknya berfungsi! Bahkan untuk mode CFB. Jadi saya kira pertanyaan saya berikutnya adalah, bagaimana cara saya mendapatkan 128 untuk bekerja (dan semoga ini akan mengakhiri pertanyaan ini)?


1
2018-06-08 23:05