这是代码,结果看起来非常有趣:
简单版本:
$str1 = hex2bin('71f6f2170242774f6252191ff08b6d50e8762d49b46fe105d7bed9a563156971806f6f34dccdff148366a79830c4529a5052a7db6c7034577e5fe4912a7960e95b4f40c20015');
$str2 = hex2bin('71f6f2170242774f6252191ff08b6d50e8762d49b46fe105d7bed9a563156971806f6f34dccdff148366a79830c4529a5052a7db6c7034577e5fe4912a7960e95b4f40c2');
$hash = password_hash($str1, PASSWORD_DEFAULT);
var_dump(password_verify($str2, $hash)); // export: bool(true)
更复杂的版本:
$pass = 0;
$fail = 0;
for ($i = 0; $i < 20; $i++) {
$password_org = random_bytes(70);
$hash = password_hash($password_org, PASSWORD_DEFAULT);
$password = substr($password_org, 0, 68);
if (password_verify($password, $hash)) {
var_dump([bin2hex($password_org), bin2hex($password)]);
$pass++;
} else {
$fail++;
}
}
echo "Pass: $pass\nFail: $fail\n";
结果总是显示一些失败,一些通过。 我找不到http://php.net/manual/en/function.password-verify.php的答案,任何人都有任何想法?
答案 0 :(得分:1)
这是因为random_bytes或hex2bin会生成意外的中断字符(\ 0),当您将其传递给password_hash时,实际密码会被截断,为此,当您使用substr时,有时会使用真实密码(由中断字符截断) )更短。
如果使用bin2hex函数$password_org = bin2hex(random_bytes(70));
进行换行,则总是失败。
答案 1 :(得分:0)
在@Clemen的帮助下,我找到了答案,password_verify无法正常处理\ 00~ \ 20。解决它(我不知道它是否理想,可能是一个不好的做法):
更改自:
$password_org = random_bytes(70);
要
$password_org = preg_replace_callback('/[\x00-\x20]/', function($str) {
return hex2bin(dechex(random_int(33, 255)));
}, random_bytes(70));