Crypt 使用相同的输入数据生成不同的哈希,并且 [以下] 以前运行的哈希生成器/检查不再用于验证用户:
public static function blowfish($password, $storedpass = false) {
//if encrypted data is passed, check it against input ($info)
if ($storedpass) {
if (substr($storedpass, 0, 60) == crypt($password, "$2y$08$".substr($storedpass, 60))) {
return true;
} else {
return false;
}
} else {
//make a salt and hash it with input, and add salt to end
$salt = "";
for ($i = 0; $i < 22; $i++) {
$salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
}
//return 82 char string (60 char hash & 22 char salt)
return crypt($password, "$2y$08$".$salt).$salt;
}
}
我把头撞在墙上,没有找到Zend的内部算法与PHP与操作系统算法之间的差异的答案;或者PHP 5.3.8与更早版本之间的差异......
编辑:我的问题在技术上得到了回答,这是我的错,我没有正确问。我已经实现了:
$salt = substr(bin2hex(openssl_random_pseudo_bytes(22)), 0, 22);
//for ($i = 0; $i < 22; $i++) {
//$salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
//}
我真正的问题是;为什么以下函数的返回方式不同?
print(substr($storedpass, 0, 60)."<br />");
返回: $2y$08$43f053b1538df81054d4cOJyrO5/j7NtZBCw6LrFof29cLBs7giK6
print(crypt($password, "$2a$08$".substr($storedpass, 60)));
返回: $2a$08$43f053b1538df81054d4cOPSGh/LMc0PZx6RC6PlXOSc61BKq/F6.
因为您是在随机数的帮助下创建salt
,
函数 mt_rand()
将在每次调用时创建随机数,可以选择使用最小值、最大参数。通常对于强加密密码哈希,应使用加密安全伪随机数生成器 (CSPRNG) 生成 Salt。
然后来谈谈你的问题,我假设 ZEND 和 php 之间的算法没有区别。因为 zend 是一个围绕核心 php 的框架,并利用它。
要验证密码,crypt
检查的工作方式是
crypt($password, $stored_hash) == $stored_hash;
一旦您在第一次哈希时存储了哈希,就很容易通过它进行验证。
这就是这里实际发生的情况,如果您将哈希作为第二个参数传递给函数 blowfish,它将通过布尔值返回验证,而不管盐如何。
if (substr($storedpass, 0, 60) == crypt($password, "$2y$08$".substr($storedpass, 60))) {
return true;
} else {
return false;
}
有关哈希和安全性的信息,请阅读此内容
希望这有帮助