在 C# 中存储使用 MD5CryptoServiceProvider 散列的密码是不是安全?

Posted

技术标签:

【中文标题】在 C# 中存储使用 MD5CryptoServiceProvider 散列的密码是不是安全?【英文标题】:Is it safe to store passwords hashed with MD5CryptoServiceProvider in C#?在 C# 中存储使用 MD5CryptoServiceProvider 散列的密码是否安全? 【发布时间】:2011-01-20 17:43:34 【问题描述】:

我们将散列密码存储在数据库表中。

我们使用 MD5CryptoServiceProvider 为每个密码添加一个随机盐值和哈希值。

这样安全吗?我听说 MD5 被“损坏”了。

如果没有,您能否推荐一种替代的哈希方法来使用(特定的 .NET 框架类)?

【问题讨论】:

好问题。我也看到了同样的说法。我期待一个知情的答复。 【参考方案1】:

哈希函数的安全性主要来自其输出(消息摘要)的长度:摘要越长,抗碰撞性越强。生日悖论告诉我们,平均而言,您希望从摘要大小的平方根的功函数中找到碰撞:换句话说,给定 128 位摘要,攻击者预计会在 2^ 之后命中paydirt 64 次试验。

MD5 多年来一直被密码学界所反对,因为它只有 128 位的摘要,而且还有一些有趣的密码分析结果可能会有效地降低其强度。 SHA1(160 位摘要)一直是首选替代方案,但即便如此,对于积极主动的对手来说,它开始看起来还不够长,而且研究界也有一些有趣的结果。 SHA-2 系列(输出大小从 224 到 512 位)是当前广泛使用的首选散列函数。 NIST 组织了一场积极的研究竞赛,以寻找 SHA-2 的继任者,但我们要到 2012 年左右才会有新的标准。

现在,在存储密码的特定情况下,我注意到您使用的是盐。这是强烈推荐的做法;如果没有盐,您将很容易受到彩虹表攻击。我相信这使您只需要考虑蛮力攻击;这就是keylength.com 的用武之地。它汇集了来自整个加密社区的密钥和摘要大小的建议,并为各种算法提供了预期的安全时间表,同时考虑了当前的计算能力并考虑了摩尔定律。考虑一下您要保护的资产类型以及密码需要多长时间才能保持安全(例如,您是否有强制的密码更改策略?)这几乎可以回答您需要的摘要大小的问题。

当然,如果您的用户使用容易猜到的密码,那么世界上最好的密码存储也无济于事。您是否向用户提供强密码提示?您是否考虑过使用密码强度计或类似工具?

【讨论】:

+1 用于解释哈希、现在使用什么以及因为您提到了他可以做些什么来提高密码强度。【参考方案2】:

我认为此时 SHA256、SHA512 更安全 :)

见wiki

【讨论】:

【参考方案3】:

不,您不应该使用 MD5。但是,您也不应该使用单轮 any 通用哈希函数,无论它在密码学上多么安全!不是 MD5,不是 SHA-1,不是 SHA-2,不是 SHA-3。

为什么?因为通用哈希函数被设计为 fast。而快速正是您在密码哈希中想要的。快速意味着当坏人获得您的数据库时,他们可以在合理的时间内对其进行简单的旧字典攻击。

你需要的是。变慢的最简单方法是迭代快速哈希函数数千次——这就是用于在类 UNIX 系统上存储密码的基于 MD5 和 SHA-1 的密码方案所做的(它不仅仅是一轮 MD5 或 SHA-1 )。另一种方法是使用设计为较慢的加密原语 - 这就是“bcrypt”密码方案的作用。

这篇 Matasano 文章 What You Need To Know About Secure Password Schemes 对这个主题有一些很好的阅读。

【讨论】:

【参考方案4】:

使用 salt MD5 比不使用要安全得多,但最好使用 SHA 哈希值之一,例如 SHA256Managed。

【讨论】:

请注意,在散列密码之前,您应该始终加盐。 用随机盐散列只能防止基于彩虹表的攻击。如果算法被破坏了,即使加盐也没用。自 2006 年 3 月 18 日起,“Klima 发布了一种算法,可以在一分钟内找到一台笔记本电脑上的碰撞,使用一种他称之为隧道的方法。”对于 MD5 en.wikipedia.org/wiki/MD5 据我了解,MD5 不应该再使用了。 我不得不同意 tobsen,MD5 是一个死算法。它已经通过多种方式被规避,并将继续受到攻击和破坏。使用更安全的东西,比如 SHA256。【参考方案5】:

存储散列密码更好,因为它隐藏密码不被 DBA 窥探。

另外,是的,MD5 已损坏,但至今仍在使用。如果您担心 MD5,请使用 SHA-1(MSDN 链接here)。它是一种类似于 MD5 的散列算法,但更强大。您可以拥有最多 512 位的 SHA-1 散列。

这是一个在 VB.NET (http://www.obviex.com/samples/hash.aspx) 上完成的示例。

以下是美国国土安全部 (US Department of Homeland Security) 说明为什么人们应该远离 MD5 (http://www.kb.cert.org/vuls/id/836068)。总结,它是“密码破解”

【讨论】:

根据 Bruce Schneier 的说法,甚至 SHA-1 也被破坏了。我们应该使用更好的哈希算法***.com/questions/720710/better-hashing-than-sha1 是的,Schneier 表明 SHA-1 不是无冲突的。 SHA-2 可用(我不知道 .NET),并且 NIST 正在开发 SHA-3。事实上,任何 SHA 都优于 MD5。 SHA1 漏洞最初是在大约 5 年前公布的。从那时起,计算能力和能力增加了许多倍。一个简单的事实是,绕过 MD5 或 SHA1 在这些天是完全可行的,而且攻击者的可能性只会变得更好。即使加盐,攻击也是截断碰撞攻击,这意味着 salt+SHA1 实际上是无用的(考虑到生日悖论)。如果你想要稳定的、长期的安全性,不要使用 MD5 或 SHA1。使用 SHA256 或更高版本。

以上是关于在 C# 中存储使用 MD5CryptoServiceProvider 散列的密码是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 C# 在 ArrayList 中存储多种数据类型?

在 C# 中使用存储过程输出参数

使用 C# 从存储在 azure blob 存储中的 200gb 文本文件中读取一行

使用 C# 和 Oracle 在存储函数中传递参数

C#中使用Oracle存储过程返回结果集

在 C# 中使用 mysql 文档存储(Nosql)中的日期字段进行过滤