代码奔腾 · 2015年10月7日 0

C#的Rijndael、AES、AesManaged、AesCryptoServiceProvider类整理分析

最近又在搞C#的加密,说实话,CSCrypt项目的开发真让我涨了很多知识。

我在开发CSCrypt的过程中发现一个很有趣的现象,用Rijndael类加密的时候,即使不设置CipherMode、PaddingMode、KeySize、BlockSize,加密解密一样能正常运作。我感觉有点奇怪,并且非常疑惑,因为我以往在网上看到别人写的AES加密例子,都是用Rijndael类实现的,那么为什么AES需要设置的属性,到了Rijndael却不是必须设置的呢?如果我没有设定,那么它默认又是用什么参数呢?

带着疑问谷歌了好久都找不到我想要的答案。反而找到了微软MSDN中的一个建议:

Rijndael 类是Aes算法的早期版本。 应使用Aes方法代替Rijndael。 更多信息,请在.NET安全博客中参见项 The Differences Between Rijndael and AES(Rijndael和AES之间的差异)。

原来C#是带有AES类的,可以直接调用,无需非要Rijndael来实现。从.NET 3.5版本开始,C#就有AES类了,而Rijndael类在每一个版本都有。

后来我又再搜索了一下,根据我在国外网站搜索到的资料分析,我简单将C#中的有关AES加密的类说一下。

Rijndael、AES、AesManaged、AesCryptoServiceProvider类的说明

  • Rijndael类:表示Rijndael对称加密算法的所有实现必须从其继承的基类。
  • Aes类:表示高级加密标准(AES)的所有实现都必须从中继承的抽象基类。
  • AesManaged类:提供高级加密标准(AES)对称算法的托管实现(RijndaelManaged 类与它类似,故此不谈。)
  • AesCryptoServiceProvider类:使用高级加密标准(AES)算法的加密应用程序编程接口(CAPI)实现来执行对称加密和解密。

Rijndael、AES、AesManaged、AesCryptoServiceProvider类的对比

  • Rijndael是AES的早期版本,也就是在它被选为AES那个时候的版本。
  • AES 算法实质上是具有固定块大小和迭代计数的 Rijndael 对称算法。
  • Rijndael的BlockSize支持128, 160, 192, 224, 256bits。
  • AES的BlockSize只能是128bits。
  • AesManaged类的功能与 RijndaelManaged 类相同,但它将块限制为 128 位,且不允许反馈模式。
  • AesCryptoServiceProvider类符合FIPS标准,并且调用Windows加密API,使用Rsaenh.dll,并已通过NIST的CMVP验证,而其他的类都不符合FIPS标准,也没有通过验证。

线程安全

上述所说的类型的任何公共 static成员线程都是安全的。但不保证所有实例成员都是线程安全的。

结论

如果你想在你的应用程式上使用标准的AES算法,建议使用AesCryptoServiceProvider类,如果你想在你的应用程式上混用RijndaelManged类和AesCryptoServiceProvider类,建议使用CBC模式代替CFB模式,它们的CBC模式实现是相同的。

如果你想用RijndaelManged类实现AES,你必须将BlockSize设置为128bits,必须将feedbacksize设置为128bits,并且不能使用CFB模式。

参考与引用

  1. The Differences Between Rijndael and AES
  2. Aes
  3. Rijndael 类
  4. AesManaged 类
  5. AesCryptoServiceProvider 类
  6. RijndaelManaged vs AesCryptoServiceProvider (AES Encryption)
  7. Why are RijndaelManaged and AesCryptoServiceProvider returning different results?
  8. 高级加密标准