22

有没有什么东西是不容易破碎的?

4

11 回答 11

44

这个 2008 年的答案现在危险地过时了。SHA(所有变体)现在很容易破解,现在(截至 2013 年 1 月)最佳实践是使用密钥拉伸散列(如 PBKDF2)或理想情况下是 RAM 密集型散列(如Bcrypt)并添加每个用户的盐也。

第2、3、4点还是值得关注的。

有关更多信息,请参阅IT 安全 SE 网站


2008年原始答案:

  1. 使用经过验证的算法。SHA-256 在数据库中使用 64 个字符,但在列上的索引没有问题,它是经过验证的哈希,比 MD5 和 SHA-1 更可靠。作为标准安全套件的一部分,它也以大多数语言实现。但是,如果您使用 SHA-1,请不要感到难过。

  2. 不要只是散列密码,还要将其他信息放入其中。您经常使用“用户名:密码:salt”或类似的哈希值,而不仅仅是密码,但如果您使用它,那么您会更难运行字典攻击。

  3. 安全是一个艰难的领域,不要认为你可以发明自己的算法和协议。

  4. 不要写像“[AddUser] Hash of GeorgeBush:Rep4Lyfe:ASOIJNTY is xyz”这样的日志

于 2008-09-22T18:51:23.313 回答
32

密码学和密码存储的第一条规则是“不要自己发明”,但如果你必须这样做,这是你必须做的绝对最低限度的安全措施:

基本规则:

  1. 永远不要存储纯文本密码(这意味着您也永远不能显示或传输它。)
  2. 切勿通过不安全的线路(纯文本、编码或散列)传输存储的密码表示。
  3. 速度是你的敌人。
  4. 随着硬件和密码分析的改进,定期重新分析和改进您的流程。
  5. 密码学和过程是解决方案的一部分。
  6. 故障点包括:存储、客户端、传输、处理、用户、法律保证、入侵和管理员。

脚步:

  1. 强制执行一些合理的最低密码要求。
  2. 经常更改密码。
  3. 使用你能得到的最强哈希——这里建议使用SHA-256 。
  4. 将密码与固定盐相结合(整个数据库相同)。
  5. 将上一步的结果与存储并附加到该记录 的唯一盐(可能是用户名、记录 id、guid、长随机数等)结合起来。
  6. 多次运行哈希算法——比如 1000+ 次。理想情况下,每次在前一个哈希中都包含不同的盐。速度是你的敌人,多次迭代会降低速度。每隔一段时间就会将迭代加倍(这需要捕获一个新的哈希值——下次他们更改密码时再做一次。)

哦,除非您正在运行 SSL 或其他一些线路安全,否则不要让您的密码以纯文本形式传输。如果您只是将来自客户端的最终哈希值与您存储的哈希值进行比较,那么也不允许以纯文本形式传输它。您需要向客户端发送一个随机数(使用一次的数字),并让他们使用生成的哈希(使用上述步骤)哈希对其进行哈希处理,然后他们将其发送给您。在服务器端,您运行相同的进程并查看两个一次性哈希是否匹配。然后处理掉它们。有一种更好的方法,但这是最简单的方法。

于 2008-09-23T18:58:08.250 回答
16

CodingHorror 去年有一篇很棒的文章。文末推荐的是bcrypt。

于 2008-09-22T18:43:43.037 回答
8

上述算法是加密安全的散列算法(但 MD5 现在不被认为是安全的)。

但是,有一些算法是专门为从密码中派生密钥而创建的。这些是关键派生函数。它们是为与对称密码一起使用而设计的,但它们也适用于存储密码。例如, PBKDF2使用盐、大量迭代和良好的散列函数。如果你有一个库,什么实现它(例如.NET),我认为你应该考虑它。

于 2008-09-22T19:13:44.010 回答
6

使用强大的加密哈希函数,如 MD5 或 SHA1,但请确保使用良好的salt,否则您将容易受到彩虹表攻击。

于 2008-09-22T18:45:24.967 回答
6

向哈希密码值添加唯一的盐(将盐值存储在数据库中)。当使用独特的盐时,使用比 SHA1 或 MD5 更安全的算法的好处并不是真正必要的(在这一点上,它是一个增量改进,而使用盐是一个巨大的改进)。

于 2008-09-22T18:55:15.630 回答
5

2013 年 1 月更新

最初的答案是从 2008 年开始的,在过去的 5 年里事情发生了一些变化。云计算和强大的并行处理器图形卡的现成可用性意味着密码多达 8 或 9 个字符散列为 MD5 或 SHA1 现在可以轻松破解。

现在长盐是必须的,像 SHA512 这样更硬的东西也是必须的。

然而,所有 SHA 变体哈希都是为通信加密而设计的——消息来回加密,每条消息都被加密,因此它们被设计为快速

在密码散列世界中,这种设计是一个很大的缺点,因为生成散列的速度越快,生成大量散列所需的时间就越少。

像 SHA512 这样的快速哈希每秒可以生成数百万甚至数十亿次。投入廉价的并行处理,密码的每一种可能的排列都成为绝对必须的。

按键拉伸是解决此问题的一种方法。密钥拉伸算法(如 PBKDF2)应用更快的哈希(如 SHA512)数千次,通常导致哈希生成需要 1/5 秒左右。登录的人不会注意到,但如果你每秒只能生成 5 个哈希值,那么暴力攻击会更加困难。

其次,应该总是有一个每个用户的随机盐。这可以随机生成为哈希的前n个字节(然后将其剥离并添加到密码文本中以在构建哈希进行比较之前进行检查)或作为额外的 DB 列。

所以:

我应该使用什么算法将密码散列到我的数据库中?

  • 键拉伸以减慢哈希生成。我可能会选择 PBKDF2。

  • 每用户盐意味着每个用户的新攻击,并且一些工作弄清楚如何获得盐。

计算能力和可用性呈指数级增长——这些规则很可能在 4 年内再次改变。如果您需要面向未来的安全性,我会研究 bcrypt/scrypt 风格的哈希 - 这些采用较慢的密钥拉伸算法并添加一个使用大量 RAM 来生成哈希的步骤。使用如此多的 RAM 会降低廉价并行处理器的效率。

2008 年 9 月的原件(留下来让评论有意义)

MD5+salt 或 SHA1+salt 不是“易碎的”——大多数黑客都依赖于巨大的彩虹表,而这些对 salt 的用处不大[update, now they are]

MD5+salt 是一个相对较弱的选项,但它不会被轻易破解[update, now it is very easy to break]

SHA2 一直上升到 512 - 使用现成的工具包几乎不可能破解[update, pretty easy up to 9 char passwords now]- 尽管我确信某个军事掩体中有一个 Cray 可以做到这一点[You can now rent this 'Cray' from Amazon]

于 2008-09-22T18:57:24.330 回答
2

MD5 或 SHA 与每个条目的随机生成的盐值相结合

于 2008-09-22T18:45:13.640 回答
1

如前所述,不应使用简单的散列算法,原因如下:

http://arstechnica.com/security/2012/08/passwords-under-assault/

所以使用其他东西,比如http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

于 2013-01-22T12:49:00.007 回答
0

所有散列算法都容易受到“字典攻击”。这只是攻击者拥有一个非常大的可能密码字典的地方,并且他们对所有密码进行了哈希处理。然后,他们查看这些哈希中是否有任何与他们要解密的密码的哈希匹配。这种技术可以轻松测试数百万个密码。这就是为什么您需要避免使用任何可远程预测的密码。

但是,如果你愿意接受字典攻击的威胁,MD5 和 SHA1 就足够了。SHA1 更安全,但对于大多数应用程序来说,这确实不是一个显着的改进。

于 2008-09-22T18:47:42.107 回答
-2

MD5 / SHA1 哈希都是不错的选择。MD5 略弱于 SHA1。

于 2008-09-22T18:43:11.960 回答