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

问题描述 投票:33回答:4

在.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();
    }
c# .net hash md5
4个回答
31
投票

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

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

public sealed class MD5CryptoServiceProvider : MD5

public abstract class MD5 : HashAlgorithm

看看定义。

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

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


10
投票

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


2
投票

我的2美分。

MD5增加了一点开销,与MD5CryptoServiceProvider相比,它更慢

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

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

差不多慢了1.5倍。

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


1
投票

您还可以使用以下方法之一创建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(下一代加密)

微软称Cryptographic Service Provider已被弃用,未来的Windows版本可能会被删除,并表示CNG是CryptoAPI的长期替代品。

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

  • “CryptoServiceProvider”用于调用CryptoAPI Win32 API的类。
  • 调用CNG Win32 API的类的“Cng”。
  • “托管”用于纯.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。

有关微软关于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方法没有选择算法,微软可能还没有计划在Windows上实现CNG。自CNG添加到Vista之后,MD5Cng从.NET Framework 3.5开始存在。

与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上执行时执行总是比在字节数组上执行快一点。

此帖子的哈希证实它未被外国代理修改: 1c84TiredWithMSDNwrittenByAncientEgyptians4cfebef40b0ae0a906b97c7

© www.soinside.com 2019 - 2024. All rights reserved.