为什么字符串散列哈希值为哈希返回哈希?

时间:2013-11-09 21:06:12

标签: php security hash passwords

我正在阅读PHP中的密码安全性,我偶然发现了一个有趣的声明:

  

使用哈希值散列密码,因为salt返回相同的哈希值

没有多想,我继续php.net,发现说的是同样的事情。

让我们看一个例子:

crypt("test", "test"); -> teH0wLIpW0gyQ
crypt("test", "teH0wLIpW0gyQ"); -> teH0wLIpW0gyQ

我完全可以理解PHP中的crypt会生成给定字符串的单向散列。

  1. 我不明白的是我们如何使用两种完全不同的盐获得相同的哈希输出?
  2. 这是否意味着可能有其他盐可能会给我相同的哈希?
  3. 跟进

    谢谢大家的指示。我现在可以看到默认行为是只使用salt的前两个字符,这完全回答了我的所有问题。感觉像傻事,但......

2 个答案:

答案 0 :(得分:5)

这是故意的。当第二个参数由字母和数字组成时,您的crypt函数仅使用两个“salt”的第一个字符进行加密,这两个字符放在结果的开头。 所以,

crypt("test", "test");        -> teH0wLIpW0gyQ
crypt("test", "te");          -> teH0wLIpW0gyQ
crypt("test", "tea");         -> teH0wLIpW0gyQ
crypt("test", "temperature"); -> teH0wLIpW0gyQ
etc.

这样做是为了便于密码正确性检查,以便
crypt($password, crypt($password, $salt)) == crypt($password, $salt)

答案 1 :(得分:3)

  

1。我不明白的是我们如何使用两种完全不同的盐获得相同的哈希输出?

虽然你为crypt函数提供了不同的盐,但它在内部使用相同的盐,i。 e。,te。这是由于crypt的实施方式:

  

标准的基于DES的哈希,字母“./0-9A-Za-z”中带有两个字符的盐。

因此,即使你提供的盐超过2个字符,也只需要前两个。

由于crypt的输出包含预先计算好的散列的用过的盐,因此使用crypt散列作为salt会产生完全相同的输出。这很完美,因为以下内容可用于验证存储的密码:

crypt($password, $hash) === $hash


  

2。这是否意味着可能有其他盐可能会给我相同的哈希?

是。 This does also apply to other crypt algorithms like bcrypt.