首页 > 解决方案 > PHP password_hash() 显示一些不寻常的行为?也许我错了?

问题描述

我在 password_hash 函数中看到了一些不寻常的行为,也许我错了,但请检查一下:

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

它返回这样的散列字符串:

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

在我看来,它不应该只返回 false 吗?

标签: phppassword-hash

解决方案


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

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

var_dump(password_verify("\0", $var));

最终var_dump()生成bool(true)显示您确实使用密码中的前导空字节创建了一个哈希。这是预期的行为,password_hash()因为它只会在错误时返回 NULL

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

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

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

var_dump(password_verify("\0", $hashed));

从. bool(false)_password_verify()

底线

除非您尝试做一些棘手的事情,例如预先散列您的密码,否则您在这里发现的是设计使然。没有人输入除字符串以外的任何内容作为他们的密码(您可以仔细检查密码,但不要清除它们,以确保它是一个被认为是系带吊带的字符串)并且您永远不应该遇到输入 NULL 字节的情况。


推荐阅读