2009-06-05 14 views
32

Đây là ví dụ mà tôi đã chạy. Nó có cùng một chế độ, Padding, BlockSize, KeySize. Tôi đang sử dụng cùng một vector init, khóa và dữ liệu.Tại sao RijndaelManaged và AesCryptoServiceProvider trả về các kết quả khác nhau?

Sử dụng RijndaelManaged tạo ra một giá trị được mã hóa của: 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

Sử dụng AesCryptoServiceProvider tạo ra một giá trị được mã hóa của: 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

Đây là mã tôi đã sử dụng để tạo các kết quả này

 

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

Tôi đoán tôi chỉ tự hỏi nếu tôi bỏ lỡ điều gì đó.

Cập nhật: Bật ra rằng AesManaged sẽ ném một ngoại lệ CryptographicException ("Chế độ mã hóa được chỉ định không hợp lệ cho thuật toán này") nếu bạn thử và đặt CipherMode thành CFB. Tôi cảm thấy rằng các AesCryptoServiceProvider nên làm điều đó tương tự, nhưng nó không. Có vẻ buồn cười rằng lớp FIPS Certified cho phép các chế độ mã hóa không hợp lệ.

+0

Câu hỏi này được đưa ra thảo luận về: http://stackoverflow.com/questions/939040/when-will-c-aes-algorithm-be-fips-compliant –

Trả lời

40

Phản hồi từ Microsoft:

RijndaelManaged lớp và AesCryptoServiceProvider lớp hai triển khai khác nhau. RijndaelManaged lớp là một loại thi hành Rijndael thuật toán trong khuôn khổ .net, mà đã không xác nhận dưới NIST (Viện tiêu chuẩn quốc gia và Công nghệ) Cryptographic Mô-đun Validation Chương trình (CMVP).

Tuy nhiên, AesCryptoServiceProvider lớp gọi Windows API Crypto, trong đó sử dụng RSAENH.DLL, và đã được xác nhận bởi NIST trong CMVP. Mặc dù thuật toán Rijndael là chiến thắng của cuộc thi NIST để chọn thuật toán sẽ trở thành AES, có một số khác biệt giữa Rijndael và AES chính thức. Do đó, Lớp Rijndael được quản lý và AesCryptoServiceProvider lớp học có sự khác biệt tinh tế khi triển khai.

Ngoài ra, RijndaelManaged lớp không thể cung cấp tương đương triển khai với AES. Có một lớp khác được triển khai trong .net khuôn khổ, AesManaged lớp. Lớp học này chỉ gói RijndaelManaged lớp học có kích thước khối cố định và số lần lặp lại để đạt được tiêu chuẩn AES . Tuy nhiên, nó không hỗ trợ kích thước phản hồi, đặc biệt là khi chế độ được đặt là CFB hoặc OFB, thì CryptographicException sẽ bị ném.

Để biết thêm thông tin, vui lòng tham khảo các tài liệu MSDN sau.

AesManaged ClassAesManaged.Mode Property

Nếu bạn muốn nhận tiêu chuẩn AES như thuật toán an ninh trong ứng dụng bạn, chúng tôi khuyên bạn nên sử dụng các lớp AesCryptoServiceProvider. Nếu bạn muốn để pha trộn các lớp RijndaelManged lớp và AesCryptoServiceProvider trong ứng dụng của bạn, chúng tôi đề nghị sử dụng chế độ CBC thay vì chế độ CFB trong chương trình của bạn, vì việc thực hiện chế độ CBC trong cả hai lớp là cùng.

6

Tôi nghĩ rằng nó phải làm với CipherMode.CFB. Xem this post mô tả AesManaged:

AesManaged thực sự chỉ là một wrapper xung quanh RinjdaelManaged với một số mã thêm để đảm bảo rằng bạn không thiết lập các thuật toán để hoạt động trong một cách tương thích phi AES. Ví dụ: AesManaged không cho phép bạn thay đổi kích thước khối. (Nó cũng sẽ không cho phép sử dụng chế độ CFB và OFB vì cách mà RijndaelQuản lý được quản lý với các chế độ ).

Lưu ý rằng nếu bạn sử dụng CipherMode.ECB hoặc CipherMode.CBC, bạn sẽ thấy kết quả giống hệt nhau. Có lý do gì khiến bạn cần CFB chứ không phải CBC?

+0

Vâng, thuật toán VHDL mà chúng tôi đã mua để giao tiếp với phần mềm chỉ hỗ trợ chế độ CFB. – SwDevMan81

+0

Tôi giả định AesCryptoServiceProvider là một trong những hoạt động với khách hàng của bạn? –

+0

Vâng, theo các cuộc thảo luận khác, đó là phiên bản FIPS tuân thủ đó là những gì khách hàng muốn – SwDevMan81

1
thông tin

Addition từ this post nói:

Về cơ bản, nếu bạn muốn sử dụng RijndaelManaged như AES bạn cần phải chắc chắn rằng:
1) Kích thước khối được thiết lập đến 128 bit
2) Bạn đang không sử dụng chế độ CFB hoặc nếu bạn là kích thước phản hồi cũng là 128 bit

Ok, tuyệt. Tôi đã thêm mEncryptionType.FeedbackSize = 128; lại ví dụ ở trên của tôi và tôi nhận được một 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 

Có điều gì sai với dll System.Core rằng wouldnt hỗ trợ này, hay tôi cần phải thay đổi cái gì khác?

Trên một lưu ý phụ, nếu tôi thay đổi FeedbackSize thành 8 cho cả hai, nó có vẻ hoạt động! Ngay cả đối với chế độ CFB. Vì vậy, tôi đoán câu hỏi tiếp theo của tôi là, làm thế nào để có được 128 để làm việc (và hy vọng điều này sẽ chấm dứt câu hỏi này)?

+0

Nếu bạn có thể làm cho nó hoạt động với 8, tôi lấy nó và chạy :-) –

+0

Chúc tôi có thể, thuật toán VHDL một lần nữa dường như chỉ hỗ trợ 128 cho FeedbackSize: ( – SwDevMan81

+0

Có thể FeedbackSize được biểu thị bằng byte chứ không phải bit. 8 * 16 = 128. – Cheeso