盐和密码

23

可能是重复问题:
PHP密码的安全哈希和盐

警告:不要使用 MD5 用于密码,应该使用像 bcrypt 这样的替代方式。


对于我的密码,我是否应该像这样使用盐(盐将对每个用户进行唯一设置,并且不会直接与密码一起存储)...

$salt = sha1(md5("coders gonna code"));
$password = md5($salt.$password);

或者只使用以下内容是否可以:

$password = md5($password);
因为即使用户使用了简单密码如"password",我使用的盐值(在这种情况下)是"145ac26ff093c6e1317f7d5fb4c9fd11c77be975",所以他们的密码条目将是"145ac26ff093c6e1317f7d5fb4c9fd11c77be975password"。根据"http://howsecureismypassword.net/"的评估,这需要3千万亿年才能破解...那么您有何看法?或者我应该做得更糟,再加上"

"?
$password = md5($salt.$password.md5($salt));

如果某个人已经成功获取了盐哈希值,是否还有任何方法能够阻止他继续深入?这更像是一个声明而不是密码。


对于那些建议我按用户来处理的人...我知道,这只是一个例子。


抱歉,我忘记编辑了。 - FabianCook
4
你可以使用 PBKDF2 代替对密码进行盐处理。 - Florent
阅读此文:http://www.codinghorror.com/blog/2012/04/speed-hashing.html - Jørgen R
3
永远永远不要使用md5作为您的密码哈希算法,就算是SHA1也不会好到哪去。使用bcrypt或者像Florent建议的那样,使用PBKDF2。为什么呢?因为它的缓慢性和多个轮次可以确保攻击者必须投入大量资金和硬件才能够破解您的密码。 - Justin ᚅᚔᚈᚄᚒᚔ
1
http://codahale.com/how-to-safely-store-a-password/ - Phil Patterson
6个回答

13
您完全错误地使用了盐。盐应该是不可预测的;您的盐恰恰相反(固定)。由于固定哈希绝对没有好处,因此似乎您指望攻击者不知道盐。这就是安全通过混淆的定义,这是另一种不良实践。
您应该做的是:
  1. 使用不可预测的合理长度字符串作为盐。从大小写字母和数字等池中随机生成8个字符的字符串就可以了。
  2. 为每个用户使用不同的盐,并在他们更改密码时更改它。
  3. 从MD5(被认为已经破解)转移至另一个更适用于此应用程序的哈希函数。SHA-1更好,因为它没有被认为破解;bcrypt是最好的,因为它具有可配置的负载因子。

检查编辑。谢谢,但我知道这个。 :) - FabianCook
@SmartLemon:请适当编辑或删除您问题的前几行。仅进行小的编辑无法让我们确切地知道您在做什么。 - Jon
像这样吗?我觉得现在可以了。 - FabianCook
@SmartLemon:嗯,不行。代码的第一行仍然显示您正在使用固定盐。 - Jon
SHA-1并不被认为是已破解的,因为它本身就不是密钥派生函数。也许你想说的是PKBDF2-SHA。 - Brendan Long

13
你应该更改盐,使其针对每个用户而不是整个系统。这将使彩虹表攻击对密码哈希更加不便。Troy Hunt在article中有一篇关于盐的演变的好文章。 编辑 $salt是每个密码记录的独特内容,它为其添加了很多熵。通常这是一个随机的字节序列,与用户账户一起存储。
传统上,在拼接salt+password后进行哈希处理。
$passwordHash = hash($salt.$password);

正如其他人所说,不要使用MD5进行哈希。它已经被破解了。

在哈希之前对密码或盐应用其他专有算法不推荐。相反,应该考虑使用行业强度解决方案,例如PBKDF2,除了加盐外,还需要进行许多(通常> 10k)重复迭代,这将进一步减缓攻击者的速度。

如果采用OWASP指南,则应定期增加执行的哈希次数(以抵消摩尔定律)。哈希次数还应针对每个用户进行持久化存储,这意味着您需要存储哈希密码、盐和迭代次数的三元组。


检查编辑。谢谢,但我知道这个。 :) - FabianCook
2
我认为这是最好的答案,因为在我看来,OP不清楚为什么应该在密码中使用盐。如果您使用固定的盐,那么无论暴力破解需要多长时间(即使需要30亿年),攻击者只需查看您的数据库表,就会发现有3000个密码具有相同的哈希值,并猜测它可能是“password”或“12345”或其他内容。您使用动态哈希,因此无法通过统计手段猜测哈希和盐的密码。 - Richard Otvos

9

2
大家都认为这是正确的吗?我也这么认为。 - FabianCook
1
Sha256并不是非常安全,说实话,这里还有一个正确使用字节范围盐的bcrypt工作版本:https://dev59.com/4G445IYBdhLWcg3wkLLU - Sammaye

4
首先,你应该永远不要直接存储md5,这一点你已经认识到了。 PHP 5.5将带来新的方法,在一行代码中轻松创建和验证密码。在那之前,您可以使用https://github.com/ircmaxell/password_compat(向前兼容)生成和验证安全密码哈希值。

3

我认为这里对盐的理解有误。盐的想法是它应该对每个哈希值都是唯一的。原因是当您创建哈希时,某些不同的字符串可能具有相同的哈希值。

在你的例子中,你也将password加入了哈希,所以它不会像这样看起来:145ac26ff093c6e1317f7d5fb4c9fd11c77be975password

P.S. 使用bcrypt。它更可靠。


1

盐应该是完全随机的,与您存储哈希值的实际密码无关。

您真正应该做的是生成完全随机的盐,然后执行

$password = md5($salt.$password);

并存储用户的用户名、盐和哈希密码。


1
不要使用MD5,它不安全。 - user529758
检查编辑。谢谢,但我知道这个。 :) - FabianCook
@Yogesh Suthar http://en.m.wikipedia.org/wiki/MD5#section_1 - user529758

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