PHP password_hash() 显示一些异常行为?也许我错了?

PHP password_hash() shows some unusual behaviour? Maybe i'm wrong?

我看到 password_hash 函数有一些异常行为,也许我错了,但请检查一下:

$var = password_hash(false, PASSWORD_DEFAULT, ['cost' => 10]);
$var = password_hash(null, PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($var);

它 return 的散列字符串如下:

string(60) "y$MCkQPQcCxL5.ERZ5pJRA.en/MolCwd015OcqNk2zh.ajpicLxONge"

在我看来它不应该return只是假的?

基于此blog,您可以看到密码中允许使用 false 和 NULL 值,并将生成哈希值。如果将 falsenull 更改为空字符串,您还会看到使用前导字节生成的哈希值返回相同的结果。您可以轻松测试前导空字节:

$var = password_hash(null, PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($var);

var_dump(password_verify("[=10=]", $var));

最后的 var_dump() 生成 bool(true) 显示您确实使用密码中的前导空字节创建了哈希。这是 password_hash() 的预期行为,因为它只会 return NULL on an error.

所以这真的不是问题,因为没有人在他们的密码中使用 NULL 字节。只有当您尝试“推出自己的”密码术并且您通常传递的字符串根本不是字符串时,它才会成为一个问题。

即使您尝试在字符串中设置 NULL 字节,它实际上也只是一个字符串:

$hashed = password_hash('[=11=]asdfghjkl', PASSWORD_DEFAULT, ['cost' => 10]);
var_dump($hashed);

var_dump(password_verify("[=11=]", $hashed));

其中 returns bool(false) 来自 password_verify().

底线

除非你想做一些棘手的事情,比如预先散列你的密码,否则你在这里发现的是设计使然。没有人输入除字符串以外的任何密码作为密码(你可以仔细检查密码,,以确保它是一个字符串,可以被认为是穿着带腰带的吊带),你永远不应该 运行 在输入 NULL 字节的情况下。