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

发布于 2024-08-28 13:58:26 字数 974 浏览 6 评论 0原文

在.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();
    }

In the .NET framework there are a couple of ways to calculate an MD5 hash it seems, however there is something I don't understand;

What is the distinction between the following? What sets them apart from eachother? They seem to produce identical results:

    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();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酒废 2024-09-04 13:58:27

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

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

public sealed class MD5CryptoServiceProvider : MD5 { }

public abstract class MD5 : HashAlgorithm { }

看一下定义。

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

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

System.Security.Cryptography.MD5.Create() is actually creating a MD5CryptoServiceProvider. That is why you see the same results.

Looking at the definition MD5 is the base class and it's abstract. I'm guessing they added the public create function for ease of use.

public sealed class MD5CryptoServiceProvider : MD5 { }

public abstract class MD5 : HashAlgorithm { }

Take a look at the definitions.

MD5 Represents the abstract class from which all implementations of the MD5 hash algorithm inherit.

MD5CryptoServiceProvider Computes the MD5 hash value for the input data using the implementation provided by the cryptographic service provider (CSP). This class cannot be inherited.

一腔孤↑勇 2024-09-04 13:58:27

正如 Jason Rowe 提到的(请投票支持他的答案,这只是一个警告),没有功能上的区别。但是,如果您正在考虑 MD5Managed(或任何名称中带有 Managed 的加密类),则存在差异。当通过组策略启用符合 FIPS 的加密算法时,无法使用托管命名的类。

As Jason Rowe mentioned (please vote for his answer, this is just a word of warning), there is no functional difference. However, there is a difference if you are considering MD5Managed (or any cryptography class with Managed in the name). Managed-named classes cannot be used when FIPS-compliant encryption algorithms are enabled via Group Policy.

红ご颜醉 2024-09-04 13:58:27

您还可以通过以下方式之一创建 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 表示加密服务提供程序已被弃用,并且可能会在未来的 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)
SHA256Managed:x 4.8 (.NET Framework 1.1)

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

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

此帖子的哈希值,用于验证其未被外国代理修改:
1c84TiredWithMSDN由古埃及人编写4cfebef40b0ae0a906b97c7

You can also create a MD5CryptoServiceProvider object one of these ways:
(MD5CryptoServiceProvider) HashAlgorithm.Create("MD5");
(MD5CryptoServiceProvider) HashAlgorithm.Create("System.Security.Cryptography.MD5");

All MD5 classes return same hashes because MD5 is a standard algorithm not because their code is the same.

But the way to create a MD5CryptoServiceProvider object is not the only choice.

US government computers running Windows must have FIPS mode enabled. This mode ensures that cryptographic code used is NIST validated.

The various .NET cryptographic classes usually exist in several versions. One version uses pure .NET code while the others call a Win32 API cryptographic function.

The various Win32 cryptographic APIs are:

  • Windows NT 4 cryptographic API: CAPI (CryptoAPI). My understanding is CSP (Cryptographic Service Provider) is a cryptographic API above the CryptoAPI.
  • Windows Vista cryptographic API: CNG (Cryptography Next Generation)

Microsoft says Cryptographic Service Provider is deprecated and may be removed in future Windows versions and says CNG is the long-term replacement for the CryptoAPI.

The .NET cryptographic classes names usually have these suffixes:

  • "CryptoServiceProvider" for the classes that call the CryptoAPI Win32 API.
  • "Cng" for the classes that call the CNG Win32 API.
  • "Managed" for the pure .NET code classes.

Some Win32 API may not be FIPS conformant and it seems that for an undisclosed reason Microsoft did not asked or could not obtain FIPS validation for cryptographic .NET pure code.

Classes that are not FIPS conformant rise a CryptographicException on computers that have FIPS mode enabled. This is mentioned in their documentation.

So, if your program is not intended to run on a US government PC you are free to use the fastest class.

About MD5, as classes names suggest, MD5CryptoServiceProvider class should call the very old and to be deprecated CryptoAPI and is FIPS conformant, while MD5Cng class calls the CNG API and is not FIPS conformant. This shows MD5 may not be usable on US government computers on future Windows versions. In fact, MD5 .NET classes documentation recommends replacing MD5 by SHA256 or SHA512.

For more on the ambiguous position of Microsoft about FIPS see:
https://blogs.technet.microsoft.com/secguide/2014/04/07/why-were-not-recommending-fips-mode-anymore/

MD5CryptoServiceProvider exists from .NET Framework 1.1. MD5CryptoServiceProvider class was added at Windows XP time. At that time the underlying Win32 CNG API did not exist. So MD5.Create method had no choice of algorithm and Microsoft probably did not yet plan to implement CNG on Windows. MD5Cng exists since .NET Framework 3.5, after CNG was added to Vista.

Approximative execution time compared to MD5CryptoServiceProvider (lower is better):
MD5Cng: x 1.08 (.NET Framework 3.5)
SHA256CryptoServiceProvider: x 2.5 (.NET Framework 3.5)
SHA256Cng: x 2.4 (.NET Framework 3.5)
SHA256Managed: x 4.8 (.NET Framework 1.1)

These unexpected results show SHA256Managed .NET pure code implementation is slower.
At the time SHA256Managed was implemented the better performing Windows Vista CNG did not exist.

Execution is always a little faster when performed on a Stream than on a byte array.

Hash for this post to verify it was not modified by a foreign agent:
1c84TiredWithMSDNwrittenByAncientEgyptians4cfebef40b0ae0a906b97c7

零度℉ 2024-09-04 13:58:27

我的2分钱。

MD5CryptoServiceProvider 相比,MD5 增加了一点开销,并且速度较慢

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

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

几乎 1.5-慢几倍。

附言。在 i7 核笔记本电脑上测试

My 2 cents.

MD5 adds a little overhead and it is slower compared to MD5CryptoServiceProvider

I just ran a little stress test generating 300k hashes of a string:

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

Almost 1.5-times slower.

PS. Tested on an i7 core laptop

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文