使用MD5.Create和MD5CryptoServiceProvider有什么区别?

时间:2010-04-08 02:11:24

标签: c# .net hash md5

在.NET框架中,有几种方法可以计算MD5哈希值,但有些东西我不明白;

以下区别有什么区别?是什么让他们与众不同?他们似乎产生了相同的结果:

    public static string GetMD5Hash(string str)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] bytes = ASCIIEncoding.Default.GetBytes(str);
        byte[] encoded = md5.ComputeHash(bytes);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < encoded.Length; i++)
            sb.Append(encoded[i].ToString("x2"));

        return sb.ToString();
    }

    public static string GetMD5Hash2(string str)
    {
        System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
        byte[] bytes = Encoding.Default.GetBytes(str);
        byte[] encoded = md5.ComputeHash(bytes);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < encoded.Length; i++)
            sb.Append(encoded[i].ToString("x2"));

        return sb.ToString();
    }

4 个答案:

答案 0 :(得分:30)

System.Security.Cryptography.MD5.Create()实际上是在创建一个MD5CryptoServiceProvider。这就是为什么你会看到相同的结果。

查看定义MD5是基类,它是抽象的。我猜他们添加了公共创建功能以方便使用。

public sealed class MD5CryptoServiceProvider : MD5

public abstract class MD5 : HashAlgorithm

看一下定义。

MD5表示MD5哈希算法的所有实现都继承的抽象类。

MD5CryptoServiceProvider使用加密服务提供程序(CSP)提供的实现计算输入数据的MD5哈希值。这个类不能被继承。

答案 1 :(得分:10)

正如Jason Rowe所说(请投票给他答案,这只是一个警告),没有功能差异。但是,如果您考虑MD5Managed(或名称中包含Managed的任何加密类),则会有所不同。 Managed - 当通过组策略启用符合FIPS的加密算法时,不能使用命名类。

答案 2 :(得分:2)

我的2美分。

MD5

相比,

MD5CryptoServiceProvider增加了一点开销,更慢

我刚刚进行了一次压力测试,产生了300k字符串的哈希值:

MD5CryptoServiceProvider: 00:00:01.1750834
MD5: 00:00:01.6398959

慢了1.5倍。

PS。在i7核心笔记本电脑上测试

答案 3 :(得分:0)

您还可以通过以下方式之一创建MD5CryptoServiceProvider对象:
(MD5CryptoServiceProvider)HashAlgorithm.Create(“ MD5”);
(MD5CryptoServiceProvider)HashAlgorithm.Create(“ System.Security.Cryptography.MD5”);

所有MD5类都返回相同的哈希值,因为MD5是标准算法,而不是因为它们的代码相同。

但是创建MD5CryptoServiceProvider对象的方法不是唯一的选择。

运行Windows的美国政府计算机必须启用FIPS模式。此模式确保所使用的密码经过NIST验证。

各种.NET加密类通常存在多个版本。一个版本使用纯.NET代码,而其他版本则调用Win32 API加密函数。

各种Win32加密API是:

  • Windows NT 4加密API:CAPI( CryptoAPI )。我的理解是CSP(加密服务提供商)是CryptoAPI之上的加密API。
  • Windows Vista加密API: CNG (下一代加密技术)

Microsoft说,不赞成使用Cryptographic Service Provider,并且在将来的Windows版本中可能会删除它,并说CNG是CryptoAPI的长期替代产品。

.NET加密类名称通常具有以下后缀:

  • CryptoServiceProvider ”,用于调用CryptoAPI Win32 API的类。
  • Cng ”表示调用CNG Win32 API的类。
  • 托管”代表纯.NET代码类。

某些Win32 API可能不符合FIPS,并且由于未公开的原因,Microsoft并未要求或无法获得用于加密.NET纯代码的FIPS验证。

不符合FIPS的类在启用了FIPS模式的计算机上引发CryptographicException。他们的文档中提到了这一点。

因此,如果您的程序不打算在美国政府的PC上运行,则可以自由使用最快的类。

关于MD5,正如类名称所暗示的那样,MD5CryptoServiceProvider类应调用非常老的且已弃用的CryptoAPI,并且符合FIPS,而MD5Cng类则调用CNG API,而不符合FIPS。这表明MD5可能无法在将来的Windows版本上的美国政府计算机上使用。实际上,MD5 .NET类文档建议使用SHA256或SHA512替换MD5。

有关Microsoft在FIPS上模棱两可的立场的更多信息,请参见:
https://blogs.technet.microsoft.com/secguide/2014/04/07/why-were-not-recommending-fips-mode-anymore/

MD5CryptoServiceProvider存在于.NET Framework 1.1中。 Windows XP时添加了MD5CryptoServiceProvider类。那时基础Win32 CNG API不存在。因此MD5.Create方法没有选择算法,Microsoft可能还没有计划在Windows上实现CNG。将CNG添加到Vista后,从.NET Framework 3.5开始存在MD5Cng。

与MD5CryptoServiceProvider相比的近似执行时间(越低越好):
MD5Cng:x 1.08(.NET Framework 3.5)
SHA256CryptoServiceProvider:x 2.5(.NET Framework 3.5)
SHA256Cng:x 2.4(.NET Framework 3.5)
SHA256托管:x 4.8(.NET Framework 1.1)

这些意外结果表明SHA256Managed .NET纯代码实现速度较慢。
在实施SHA256Managed时,还没有性能更好的Windows Vista CNG。

在Stream上执行时,执行总是快于在字节数组上执行。

此帖子的哈希值,以验证该帖子未被外地代理商修改:
1c84TigerWithMSDN,由古代埃及人撰写,4cfebef40b0ae0a906b97c7