使用随机盐改进密码哈希


Improve password hashing with a random salt

我正在启动一个网站,并试图决定如何加密用户密码以将其存储在SQL数据库中。

我意识到使用简单的md5(密码)是非常不安全的。我正在考虑使用sha512(password.salt),并且我一直在研究生成有用salt的最佳方法。我读过很多文章,说盐应该尽可能随机,以将熵添加到哈希中,这看起来是个好主意。但是:

  • 你需要把随机的盐和你的杂碎一起储存
  • 考虑到攻击者以某种方式访问了你的散列密码(并试图将散列反转为纯文本),这意味着他可能丢弃了你的数据库,然后也访问了你随机的salts

数据库中散列旁边看起来很奇怪的值是salt,这不是很明显吗?如果攻击者可以访问salt和散列值,那么如何更安全呢?

有人在这方面有什么专长吗?谢谢

攻击者被"允许"知道salt-您的安全性必须设计为即使知道salt也仍然安全。

盐是干什么的

Salt使用预先计算的"彩虹表"来帮助防御暴力攻击
Salt使得暴力对攻击者来说更加昂贵(在时间/内存方面)
计算这样的表是昂贵的,并且通常只有当它可以用于多个攻击/密码时才能完成
如果你对所有密码使用相同的salt,攻击者可以预先计算这样一个表,然后强行将你的密码转换为明文
只要你为你想要存储的每个密码生成一个新的(最好的密码强)随机salt的散列,就没有问题

如果您想进一步加强安全性
你可以多次计算散列(散列散列等)——这不会花你太多钱,但它会使暴力攻击/计算"彩虹表"变得更加昂贵。。。请不要发明自己——有一些行之有效的标准方法可以做到这一点,例如http://en.wikipedia.org/wiki/PBKDF2和http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard

注意:

由于"CPU时间"(可用于彩虹表/暴力等攻击)越来越广泛(例如,亚马逊的云服务是全球速度最快的超级计算机前50名之一,任何人都可以以相对较小的数量使用),因此使用这种机制是当今的强制要求

假设攻击者以某种方式访问了你的哈希密码(并试图将散列反转为纯文本),这意味着他可能丢弃了你的数据库,然后访问了你的随机盐还有

腌制的全部目的是击败"彩虹桌":

http://en.wikipedia.org/wiki/Rainbow_table

"防御彩虹表"一节中,了解为什么足够长的盐会击败任何彩虹表。

这怎么更安全?

它过去更安全,因为它迫使攻击者尝试一种当时非常昂贵的暴力方法,而不是在预先计算的彩虹表中即时查看。如果你有一个64位的salt,攻击者需要有2^64个预先计算的彩虹表,而不是一个。。。换句话说:它让彩虹桌变得毫无用处。

然而,请注意,现代GPU每秒可以破解数十亿个密码,这使得攻击者存储巨大的彩虹表几乎毫无意义(而不是存储数十亿个哈希,只需在几秒钟内计算它们)。

现在你想用PBKDF2或scrypt之类的东西来存储你的"密码"。

散列、加盐密码的强度取决于以下所有因素:

  • 哈希算法的强度
  • 盐的随机性
  • 密码的随机性

你的系统和上面最弱的系统一样强大。

以下问题来自姐妹站点Security StackExchange。他们讨论了散列、盐、PBKDF2、bcrypt、scrypt和其他一些东西。

  • 如何安全地散列密码
  • 有安全专家建议使用bcrypt存储密码吗

这里也有一些以前关于StackOverflow的讨论:

BCrypt是一个在C#中使用的好的哈希算法吗?我在哪里能找到它?

简而言之,salt是一种保护措施,它使密码在发生泄露时需要很长时间才能恢复,就像哈希一样。如果攻击一个密码,salt不会有什么不同。如果试图使用预先计算好的字典或同时测试多个密码,则对每个条目使用不同的salt将大大增加所需的工作量,并且通常使生成合适的彩虹表变得不可行。

下面是一篇关于密码学的好文章:http://www.javacodegeeks.com/2012/02/introduction-to-strong-cryptography-p1.html

有关salt的讨论,请参阅哈希算法的真实世界用法,场景1一节。

我强烈建议使用http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html生成您的盐