在表格中的密码字段应该使用什么;MD5还是SHA1?

5

我绝对不是安全专家,甚至连新手都算不上。至多也只能算是安全方面的初学者。

有人建议我使用SHA1而不是MD5——为什么我要选择其中之一?其中一个更安全吗?


2
请注意,有些“货柜崇拜”回答声称哈希算法“破解”或“有缺陷”,但没有说明该算法的缺陷是什么。如果您在数据库中存储明文SHA-1密码哈希值,则与MD5一样存在缺陷(请参见http://en.wikipedia.org/wiki/Rainbow_table)。我认为,在安全地存储用户密码的用例中,生成哈希碰撞所需的工作量并不重要。正确的答案是使用盐、密钥哈希、PBKDF2等方法。 - dtb
+1 - 这是一个非常好的例子,一个看似无害的微小问题,实际上是进入一个更大、更混乱、更重要的雷区的绝佳入口。 - Andras Zoltan
7个回答

10

我至少会使用SHA2(256)- 但是:

仅仅在数据库中散列密码几乎没有任何意义,因为会遭受彩虹表攻击。同样,加盐哈希更好,但如果有人可以访问您的数据库,那么他们很可能可以访问您的代码,在这种情况下,他们可以轻松地破解固定的盐。同样,如果您使用随机盐,那么您将其存储在行内,因此虽然它会减慢攻击者的速度,但他们仍然可以用彩虹表攻击它。

一个更好的解决方案是使用密码加强,它使用随机盐以及随机(高)数量的迭代,以便尝试针对每个密码的暴力攻击需要显着更长的时间,因此使得破解所有密码在物理上更加困难。

我相信在.Net中可以使用PBKDF来实现这一点——但是我已经找不到了链接(有人在我之前提出的问题的答案中提供了它)。编辑-找到.Net的链接Rfc2898DeriveBytes类

关于MD5

尽管如其他答案所述,MD5确实已被证明是“破解”的,但我不使用它的主要原因 - 也是我读到它不建议使用的原因 - 是因为它实际上非常快,从而增加了在给定时间内破解的可能性。


1
@Longpoke -- 这是给你的:我的密码哈希值是"2pVji9p6NbnWV2SebMK9TruOdvsVIbenBF+fX3PJfXdv/DyBlgTpkv1tKsgGVpjzDyHoVUEvzhzZ L30mIWmiYOSZ6FcN6BJeWPrP4lCxZ4J1lmSL8MEYDyNHVFwS05LsH5jpdCir7ew32cBLaTB84a1e xmuvsim97l1H6rsx+EquMRlXg1HP9SKrjqfIWMZ4XFa4cbP8r469kZjtdkTlVEMCDtzkL8IjyfPY KKDycKrgVHDiU9X/qFgY3tgkSME0TmRukyCfzQUIkRB6kBaB7R63aPr/cs2OmfbggNL3SlLeQoNw cijKW0TuWQX4UfQY3e/uIcoDd4C8ldYN4wgCUA=="。计算它花费了{00:00:00.4656027}。这是一个可以在英语词典中找到的单词。如果你能在合理的时间范围内破解我的密码,我真的会印象深刻 :) - dtb
1
@Longpoke:这只需要标准的.NET类就可以完成三行C#代码。如果这些太多工作,那么我想我已经证明了这三行足以完全保护我的资产。如果您还想尝试,请使用以下“ A”哈希值: "3ZyM1YZhl8bFf6x99xDDBsPbm18givBckaAU561gDtHCMIwTT2urk8Z88L8f9sDaYjfpFJi06Wl3 g5i4HlaAGTP4+ADkkWHPasFVQuQ3zKjVWpOPkE40H6D7Crk3xnKjAF5bzgfeyiqupa0OKMuYrzUu YA19ypJjo4+mz++6eJbjD4/HhKFfFrpieZtSRTWk6EBy3Xd4py9bur+uDaJI6pnRJC4UYBmvF4H9 fd1NkHnrG6axut3+/WSq63R0UABpAk5g8C6ym0SRPfv6QJY7OFAPsk9QcBZGV5Lyl9XGn0qTjktX rizIypgnKHXku7Z78+FeqQ1/YtpPPvMIualJhw==" - dtb
哦,这是我在该领域的“资历”。几年前,有人从我这里偷了一个产品,所以我黑进了他们的网站,并在他们的PHP代码中植入了一个后门,可以记录密码在被哈希和检查之前。http://longpoke.blogspot.com/2008/11/crysis-wars-crysis-hack-now-availible.html?showComment=1240761366499#c8385619622646577747 - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
1
@Longpoke:真正的问题需要真正的解决方案。密码之所以作为唯一通用的身份验证手段得以生存,是有原因的。但你提出客户端证书作为更优越的解决方案。当你需要从不同的机器进行身份验证时会发生什么?客户端证书是不可移植的。那么你该如何解决这个问题呢?是的,我在给你设置陷阱。 - President James K. Polk
1
同样地,如果您使用随机盐,则无论如何都会将其存储在行内,因此虽然它会减慢攻击者的速度,但他们仍然可以使用彩虹表对其进行攻击。对于256位盐值,彩虹表需要的比特数比宇宙中的原子数还要多。您总是可以使某些东西“更安全”,但这是大多数理智人停下来并说“足够安全”的点。 - BlueRaja - Danny Pflughoeft
显示剩余17条评论

3
MD5和SHA1都被视为不安全,其中SHA-1更好。但是需要考虑以下两个方面:
1. “不安全”意味着比暴力破解更容易数学上确定先前散列的值。有时这意味着可以将计算次数从十亿减少到九千万,其他情况则少得多。但是这种情况远没有我的第二点那么不安全。 2. 因为您正在创建哈希值,所以黑客很容易通过填充一个包含常见密码的表并运行相同的哈希算法(无论您使用哪个算法),来确定您数据库的密码。这称为“彩虹表”。
例如,许多人将“password”和“john”作为密码。在MD5中,这两个密码始终转换为: password:5f4dcc3b5aa765d61d8327deb882cf99 john:527bd5b5d689e2c32ae974c6229ff785
因此,如果仅使用MD5对密码进行哈希,且某些用户足够天真以使其成为他们的密码,则如果黑客控制了您的数据库并将其与彩虹表进行比对,则可能会泄漏。
然而,如果您对每个预先散列的值添加某种无意义字符串,例如“password12345”和“johnxyz”,则会得到两个完全不同的哈希,这些哈希与上述哈希不同。这称为盐值,可以防止彩虹表产生效果。
我的建议是在编程语言中使用最高级别的SHA算法,并针对盐值进行哈希(如果您喜欢,可以通过散列当前时间来创建“随机”盐值),并将其存储在具有散列密码的数据库记录中。
数据库列:用户名|密码|盐
这不是任何人想到的最安全的系统,但可能适合您的需求。

2
您也可以使用用户名进行哈希运算,这在用户数据库中很可能是唯一的,即“随机盐”。 - Patrick
是的,如果您不需要它真正随机,那么几乎任何您想要的东西都可以使用。当然,如果您真的关心,还有一些随机数生成器可以进行哈希处理。 - Jordan
尽管哈希在安全社区的眼中可能有许多不安全的方式,但这只是其中之一。当前已知的漏洞是否影响您的应用程序并不重要:为什么要使用理论上不安全的哈希函数,而使用理论上安全的哈希函数同样容易呢?此外,最好保险起见,因为正如Bruce Schneier所说:“攻击只会变得更好,永远不会变得更糟!” :) - BlueRaja - Danny Pflughoeft

1
无论你使用哪种,都要使用加盐哈希。
祝好运。

1
存储便宜,处理器快速。使用1千字节的盐和SHA-512。


0

MD5已经被“破解”,现在更高级别的安全性需要使用SHA-2。这里有一个非常有趣的阅读材料http://en.wikipedia.org/wiki/MD5

编辑:晚了9秒 :)


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接