【问题标题】:Why is there no managed MD5 implementation in the .NET framework?为什么 .NET 框架中没有托管的 MD5 实现?
【发布时间】:2010-11-15 02:17:58
【问题描述】:

(重新编写的问题,请参阅历史原文)。

问题就在标题中。

为什么 .NET 框架中没有托管 MD5 实现?

我说的是 MD5 算法的纯托管代码实现,它在 .NET 框架中不存在。

在 System.Security.Cryptography 命名空间中,我知道 MD5 抽象基类(它必须被继承并且不能按原样使用),我也知道MD5CryptoServiceProviderMD5CNG 分别提供来自操作系统底层 CSP(加密服务提供者)和 CNG(下一代加密)提供者的实现,但是,这两个实现都是 非托管代码。

答案更新:
我很感激,虽然应该对这个问题有“一个真正的答案”,但我们(SO 社区)可能不知道它,除非 Microsoft 框架设计师(或直接了解该框架的人)参与其中然而,在这个社区中,许多人对从框架中省略托管 MD5 实现的想法提供了非常合理的“有根据的猜测”,但是,我仍然很想知道是否有人知道“真实”的答案这个问题。

【问题讨论】:

  • 每个人都错过了你的问题的重点,因为它太长了。只保留标题 + 当前的最后两段将是完美的。
  • 鉴于它是 CLI 标准库的一部分,您为什么要关心它?它的完成方式是一个实现细节。 Array.Copy 也是不受管理的,但它不会打扰任何人,也不会对客户产生任何实际后果。如果您在框架中有一个托管的 MD5 提供程序,会发生什么变化?
  • @wcoenen - 好吧,我确实有点胡扯,但是,我的问题的范围和细节在标题中就在那里,我专门使用了这些词“管理实施”至少 9 次!!!为什么这么难把握?尽管如此,我还是编辑了我的问题以缩短、澄清和提供更新。
  • 有趣的是,.NET 保持对 CryptoAPI(或 CryptoNG API)的访问,因为这些算法符合 FIPS。纯托管版本可能更快,并且保证安全,而不是特定于平台 - 但如果您启用机器策略以仅允许符合 FIPS 的算法,托管的将变得不可用
  • MD5 在任何实现中都不符合 FIPS。

标签: .net hash cryptography


【解决方案1】:

MD5CryptoServiceProvider 从第一天起就在 .NET Framework 中,实际上:

byte[] hash = new MD5CryptoServiceProvider().
    ComputeHash(Encoding.ASCII.GetBytes("Hello World!"));

请注意,所有封装散列算法的 .NET BCL 类都继承自 HashAlgorithm 类,因此可以多态地使用它们...

public byte[] ComputeHash(byte[] buffer, HashAlgorithm hashAlgorithm)
{ ...

...不同的实现可以依赖注入到你的代码中:

public HashAlgorithm HashAlgorithm { get; set; }

编辑

啊哈,我明白了。 MD5 的问题(这纯粹是推测)是它是最广泛使用的散列算法之一,因此,它的实现需要符合某些标准——更具体地说,FIPS 140-1。请参阅this 了解更多信息。

【讨论】:

  • -1 这是不正确。 MD5CryptoServiceProvider 不是托管实现。
  • @Anton - 感谢您的编辑。我很欣赏这可能是代表您的猜测,但 .NET 安全博客链接正是我提出问题时所期望的那种东西(MS 的框架设计师在这个问题上绊倒了!:)
【解决方案2】:

【讨论】:

  • 错了! MD5CryptoServiceProvider 不是 托管 实现。请查看我的问题的编辑。
  • 区别很傻。如果操作系统已经为您提供了功能,为什么还要麻烦呢? .Net 中的很多东西只是直接调用底层的 OS API。
  • @Joel - 如果您的目标是 MONO 框架或其他操作系统怎么办?有时很高兴知道您的应用程序的所有代码都完全在框架内管理和运行,而不依赖于外部库。当然,如果您使用的是 Windows,那么区别就更没有意义了,但是,我仍然很好奇为什么省略了托管实现。
  • 在这种情况下,单声道是无关紧要的。一个合规的实现必须提供功能,但它来自哪里并不重要。
  • @Joel - 有趣...我刚刚检查了 MONO 文档,发现它们包含了一个 MD5CryptoServiceProvider 类,但这使用了一个纯粹的 托管代码 实现,而不是而不是将功能委托给 OS/CSP!见这里:go-mono.com/docs/…
【解决方案3】:

从一开始就存在

// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();

// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();

// Loop through each byte of the hashed data 
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
    sBuilder.Append(data[i].ToString("x2"));
}

// Return the hexadecimal string.
string hexMD5hash = sBuilder.ToString();

【讨论】:

  • 错了! MD5.Create() 在内部创建一个 MD5CryptoServiceProvider 的实例(在 Reflector 中查看)。 MD5CryptoServiceProvider 不是 托管 实现。请查看对我的问题的修改。
  • @monkey_p - 公平地说,这个问题总是指定了一个托管实现
【解决方案4】:

由于我没有设计框架,我不能肯定地说,但我相信他们可能不会因为安全原因而阻止它的使用。

我原本认为非托管实现会更快,但现在我们知道事实并非如此,请参阅:https://stackoverflow.com/a/14850676/58391

我的下一个最佳猜测与 Pavel 在上面的 cmets 中所说的一致。与 .NET 和 C# 中的大多数功能一样,当底层的非托管功能已经足够好时,实现、测试和发布该功能可能没有足够的成本优势。

从设计该语言的人那里看到真正的答案会很有趣。

【讨论】:

  • +1 这是迄今为止唯一真正的答案。 MD5CryptoServiceProvider 的 MSDN 页面有一条说明鼓励使用更现代的哈希,所以我认为重新实现他们不推荐的算法的优先级永远不够高。 msdn.microsoft.com/en-us/library/…
  • 某些测量结果与您关于原生 CSP 更快的断言相矛盾:byterot.blogspot.de/2013/01/…
  • 另外,更多的测量表明性能不是原因:stackoverflow.com/a/14850676/58391
  • @codekaizen - 谢谢,我已经更新了答案以反映这些数据。
【解决方案5】:

MD5 不适用于任何加密或文件验证目的,除了可能的错误检测传输错误。这可能是为了让人们转向更好的哈希值,比如 SHA-1 或更佳的 SHA-256。

http://www.mscs.dal.ca/~selinger/md5collision/

【讨论】:

    【解决方案6】:

    在 .NET 中,以 CryptoServiceProvider 结尾的任何内容都会包装非托管 Windows Crypto API。以 Managed 结尾的任何内容都完全用托管语言编写。 link text

    正如其他人所说,您不应再使用 MD5。您应该使用 .NET 中具有托管实现的 SHA-256。你很高兴去换一个更好的算法。 (编辑)由于 MD5 不再是 kosher,因此几乎不可能在更高版本的 .NET 中对其进行更新以进行完全管理,因为无论如何您都不应该再使用它了。

    【讨论】:

      【解决方案7】:

      这完全是基于阅读了来自不同 Microsoft 博主的许多帖子的推测(尽管不是做出此决定的特定人)。 .NET 框架中没有托管 MD5 实现,因为:

      1) 非托管 Windows Crypto API 已经提供了一个实现,他们负担不起,或者更有可能觉得他们有更好的事情要做,而不是投入资源来实现已经从底层非托管封装的东西执行。可以通过阅读How many Microsoft employees does it take to change a lightbulb?Minus 100 points(适用于 C# 编译器,但展示了在他们做得最好的地方花费资源的相同心态)、Why Doesn't C# Implement "Top Level" Methods?(另一个看单个功能所需的资源)和features don't exist by default(链接自here)。这些都没有回答具体问题,但它们都表明编写新代码需要大量资源,这些资源可能更好地用于其他地方。您可以争辩说,封装底层非托管代码仍然需要资源,但我不认为不重写已经可用、经过测试和工作的代码会节省净成本。

      2) 稍后,或者可能几乎在同一时间,research proved the feasibility of collision attacks against MD5。那时,在托管代码中重写 MD5 的门槛可能会更高。一旦安全开发生命周期规定 don't use banned crypto 我可以想象 MD5 的托管版本将是他们投入资源的最后一件事。

      虽然我的回答完全是推测,但不难理解,即使是微软也有有限的资源和大量他们想要包含的功能。必须做出选择,而这些决定几乎总是会影响到某些开发人员。

      最后,您自己说有 3rd 方 MD5Managed 课程,或者您总是可以roll your own。 MD5 的托管版本可能是“five minute feature”,但如果确实如此,那么作为程序员,我们可以自己编写。

      【讨论】:

      • @Grant - 虽然我很欣赏这是猜测(正如您自己承认的那样),但这个答案非常有帮助并且提供了很好的洞察力。 +1 谢谢。
      猜你喜欢
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多