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

Ben*_*key 38 .net c# 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();
    }
Run Code Online (Sandbox Code Playgroud)

Jas*_*owe 31

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

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

public sealed class MD5CryptoServiceProvider : MD5

public abstract class MD5 : HashAlgorithm
Run Code Online (Sandbox Code Playgroud)

看看定义.

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

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

  • 你认为`MD5.Create()`方法作为一种工厂方法可以在今天重新编写一个`MD5CryptoServiceProvider`实例,但是它具有在未来版本中返回任何类型的MD5实现的灵活性吗?它的返回类型是`MD5`,所以如果你想让你的程序使用最新的实现,那么使用`MD5.Create()`方法. (2认同)

Mat*_*ira 10

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


fig*_*olu 5

您还可以通过以下方式之一创建 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 ”用于调用 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。MD5CryptoServiceProvider 类是在 Windows XP 时添加的。那时底层的 Win32 CNG API 并不存在。所以MD5.Create方法没有选择算法,微软可能还没有计划在Windows上实现CNG。MD5Cng 从 .NET Framework 3.5 开始存在,在 CNG 被添加到 Vista 之后。

与 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)
SHA254.NET Framework ( .x 1.08 ) 1.1)

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

在 Stream 上执行总是比在字节数组上执行要快一些。

这篇文章的哈希,以验证它没有被外国代理修改:
1c84TiredWithMSDNwrittenByAncientEgyptians4cfebef40b0ae0a906b97c7