PHP密码_hash()/ bcrypt

时间:2015-06-07 00:46:19

标签: php hash bcrypt

我正在查看bcrypt哈希算法。

我使用password_hash()的第一次测试:

echo password_hash("123", PASSWORD_BCRYPT, array( "salt" => "1234567890123456789012" ));
echo password_hash("123", PASSWORD_BCRYPT, array( "salt" => "1234567890123456789012xxxxxxxxxxxxxxx" ));

两者都将返回'$ 2y $ 10 $ 123456789012345678901uiaLpJxTpf6VbfI5NADlsRsfvEm6aq9C'。

  1. 为什么哈希是存储在哈希内部的盐?这对我来说毫无意义。如果他不知道盐,那么从数据库中获取哈希值的攻击者无法对它们做任何事情。
  2. 为什么我用两种不同的盐得到相同的哈希?是否只有用于盐的前22个字符传递给函数?
  3. 非常感谢!

2 个答案:

答案 0 :(得分:3)

salt不是秘密,它通常使用哈希存储在数据库中,也可以直接存储在哈希中,如password_hash那样。

salt创建了唯一性,因此使用彩虹表或字典之类的东西不能轻易破解散列,除了使散列更加独特之外,它并没有真正增加安全性,因此对散列运行字典或表不会匹配,因为它还包括盐。

如果省略salt,则password_hash()将为每个密码散列生成一个随机盐。这是预期的操作模式,您不应提供自己的盐 PHP7实际上会产生一个警告,告诉你不推荐使用salt选项。

传递的盐需要至少22个字符,但大多数基础算法(如bcrypt)不使用整个盐,有关详细信息,请参阅this answer

答案 1 :(得分:3)

盐不是你必须努力保守秘密的东西。即使已知,它们的保护也是有效的。 https://crackstation.net/hashing-security.htm

  

盐不需要保密。只需随机化哈希,查找表,反向查找表和彩虹表就会失效。攻击者不会事先知道盐的含量,因此无法预先计算查找表或彩虹表。如果每个用户的密码使用不同的盐进行哈希处理,则反向查找表攻击也不起作用。

由于您似乎使用固定的盐值,请注意:

  

常见的错误是在每个哈希中使用相同的salt。盐被硬编码到程序中,或者随机生成一次。这是无效的,因为如果两个用户拥有相同的密码,他们仍然会有相同的哈希值。攻击者仍然可以使用反向查找表攻击同时对每个哈希运行字典攻击。他们只需要在每次密码猜测之前将盐应用于哈希值。如果盐被硬编码成流行的产品,可以为该盐构建查找表和彩虹表,以便更容易破解产品产生的哈希值。

我建议使用password_hash而不使用其可选参数。默认功能是高度安全的,通过指定您自己的算法和选项可能会削弱其功能。

根据PHP documentation

  

注意强烈建议您不要为此功能生成自己的盐。如果您没有指定安全盐,它将自动为您创建安全盐。

编辑:这就是为什么将盐保密在bcrypt中是没有意义的。

Per this post,8个字符的密码中有3,025,989,069,143,040种可能的组合。您通常应该调整bcrypt的工作因子,以便用0.1秒来散列密码。这意味着计算所有可能性需要302,598,906,914,304秒。那是9,588 <百万年。