这是我运行的示例。它具有相同的模式,填充,块大小,键大小。我正在使用相同的初始化向量,键和数据。

使用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认证的类允许使用无效的密码模式。

最佳答案

微软的回应:
RijndaelManaged类和
AesCryptoServiceProvider类是两个
不同的实现。
RijndaelManaged类是一种
算法的实现
在.net框架中,不是
在NIST(国家标准
标准技术研究所)
密码模块验证
程序(CMVP)。

然而,
AesCryptoServiceProvider类调用
Windows Crypto API,它使用
RSAENH.DLL,并已通过验证
CMVP中的NIST。尽管里恩代尔
算法是NIST的赢家
竞争选择算法
会变成AES,有一些
Rijndael和
官方AES。所以,
Rijndael托管类和
AesCryptoServiceProvider类有
实现上的细微差异。

另外,RijndaelManaged
无法提供同等的
AES实现。有
NET中实现的另一个类
框架,AesManaged类。这
类刚刚包装了RijndaelManaged 具有固定块大小的类,并且
迭代计数以实现AES
标准。但是,它不支持
反馈量,尤其是何时
模式设置为CFB或OFB,
CryptographicException将被抛出。

有关更多信息,请参阅
以下MSDN文档。

AesManaged ClassAesManaged.Mode Property

如果您想将标准AES用作
您的安全算法
应用程序,我们建议使用
AesCryptoServiceProvider类。如果你
想要混合RijndaelManged
AesCryptoServiceProvider
您的申请,我们建议使用CBC
模式而不是CFB模式
程序,自实现以来
两个类的CBC模式是
相同的。

10-04 11:58