使用哪种算法:托管 vs. 非托管哈希算法

23
在一个正常的C#应用程序中,哪个类用于哈希:使用xxxManaged还是xxx(即SHA1Managed vs SHA1),为什么?

1
未经管理的SHA1算法包括SHA1Cng和SHA1CryptoServiceProvider。SHA1是这两个类和SHA1Managed的抽象基类。 - R. Martinho Fernandes
还可以查看此问题的答案。 - Ioanna
6个回答

16
非托管的哈希函数以***Cng结尾,例如SHA256Cng,也会有平台限制。它们比托管的替代方案要快得多,但在运行时在Windows XP上会失败。然而,如果您知道您的程序将始终在Windows 7、Vista SP1或2008上运行,它们通常会比托管版本表现得更好,即使有本地互操作开销。
如果您正在编写一个通用程序,使用***Managed类会更容易操作,因为它们始终可用。

2
@SLaks:在我的电脑上,对于大型哈希作业,最近一次的性能分析运行中,它的速度几乎是托管版本的12倍;当然,你的情况可能会有所不同...(我认为速度高度依赖于硬件和操作系统,因为它取决于是否获得了硬件加速。) - Reed Copsey
1
@SLaks:我不知道 - 我认为我的系统没有它们,但在我的测试中它仍然快得多。话虽如此,我最终使用了托管版本,只是因为我需要支持XP,并且性能不值得支持2个版本的开发/维护开销。 - Reed Copsey
1
@Reed:我以前不知道,谢谢!编写一个包装方法来检查Environment.OS并返回SHA512应该不难。 - SLaks
1
这里有一些测量数据表明,托管的实现更快:https://dev59.com/MmUq5IYBdhLWcg3wBL_j - codekaizen
1
@Xaqron "那为什么它们可用" -- 因为与“*Managed”变体不同,基于CSP的变体在Windows上是“安全”的。托管版本是用户空间代码位,根据Windows不是“安全”的。与今天提供的某些操作系统不同,Windows拥有(并且已经有一段时间了)密码学功能,这些功能可以免受用户空间篡改的影响。这就是为什么会有两个版本的原因,因为一些项目(政府)将要求使用安全的密码组件(其中结果,例如哈希或对称/非对称结果,不能从用户空间进程篡改)。 - Shaun Wilson
显示剩余10条评论

10

您应该使用*Managed版本,它们通常更快。

*CryptoProvider*CNG类使用本机交互,并且通常较慢。
但是,我听说它们可以使用硬件加速器。 (我没有检查过)

此外,本机版本已获得FIPS认证;管理版本未经认证。


2
@SLaks:我个人认为FIPS认证不仅仅是一个“也可以”的选择,它应该是决策树的顶部决策点。无论如何,感谢提及它,很少有人知道这个好玩的小细节 :) - Willem van Rumpt
@SLaks:同样正确。但是事后的合规可能会损害您的业务 ;) - Willem van Rumpt
@Martinho: 我强烈不建议您编辑Machine.config。http://msdn.microsoft.com/en-us/magazine/ee321570.aspx - SLaks
你知道任何基准测试吗? 我不确定你的说法" *Managed "变体仍然更快。我进行了一个简单的测试,比较了 SHA1Managed、SHA1Cng 和 SHA1CryptoServiceProvider。托管版本的速度大约只有未管理版本的一半(.NET 4.5,Win 8.1)。 - Dirk Vollmar
似乎这取决于输入大小,正如这个基准测试所示:https://wintermute79.wordpress.com/tag/sha1cng/ - Dirk Vollmar
显示剩余4条评论

3

*Managed 版本完全使用托管代码编写,而 *Provider 版本是 API 的包装器。因此,如果您始终使用托管版本,则您的代码将可移植到 Mono 等平台,但如果您使用 Provider 版本,则仅限于 Windows 平台。


那很有道理。 - Xaqron

2

托管库更安全易用,且不会带来 PInvoke 开销。另外,在运行时间长、内存泄漏可能导致服务器崩溃的应用程序(如 ASP.NET)中,托管库也更可取。


0

托管和CNG非托管版本之间的另一个区别是支持的.Net Framework版本:例如

  • AES托管版本从3.5开始,而CNG从4.6.2开始,对于
  • SHA512,托管从1.1开始,Cng从3.5开始。

然而,我认为如果我们不受框架版本或支持旧操作系统版本的限制,我们应该使用CNG版本

  • 后缀为Cng的哈希算法是唯一使用bcrypt的算法
  • 它可能需要更长时间实际上是一个优势,因为它可以防止暴力攻击:对于用户来说,300毫秒或3毫秒没有区别,但对于攻击者来说,这是100数量级的差距!

-1

在.NET中,托管类通常更“安全”;它们实现了Framework定义的接口,如IDisposable和ICryptoServiceProvider。但是,由于托管组件,它们会稍微慢一些。如果您需要随意创建和销毁这些辅助程序和/或需要实现基于接口的设计模式,则应使用托管类。

非托管类通常更快(因为它们预编译为机器代码),但可能难以使用。销毁非托管类的实例可能会有问题,有时甚至不可能。如果没有托管包装器可以完成相同的工作(因为您可能最终需要实现自己的包装器来处理非托管类的实例化、互操作和销毁),或者如果使用只是一次性的,则应使用这些类。


4
完全错误。它们都继承相同的基类,并且完全可以互换使用。未经管理的对象没有任何互操作问题。 - SLaks
3
它们都实现了IDisposable和ICryptoTransform,因为这些在基类HashAlgorithm中很重要。即使你是正确的,非托管版本也需要IDisposable,而不是托管版本。这就是为什么它们是托管的原因。 - R. Martinho Fernandes
我并不是“完全错误”的;我只是将“非托管”视为COM或外部访问类,而不是.NET的包装器。如果它在.NET框架中提供,那么在我的书中它就是“托管”的,无论它是包装器还是100%的.NET算法实现。框架中一半的类都是包装器,我们称它们为“托管”类。 - KeithS
相对于“*Managed”变体,它们是非托管的。无论哪种方式,您都应该删除您的答案;它与问题无关。 - SLaks
"Managed" 和 "unmanaged" 在这里有特定的含义;例如,请参见 https://msdn.microsoft.com/en-us/library/ms223095(v=vs.110).aspx。" - Mark Sowul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接