PHP crypt()河豚函数不工作

PHP crypt()河豚函数不工作,php,bcrypt,blowfish,crypt,Php,Bcrypt,Blowfish,Crypt,这是我第一次在PHP中使用crypt()函数,我不明白为什么它不起作用。我的代码基于本文: 函数blowfishHash($pw){ //生成随机盐 $salt=“$2y$10$”; 对于($i=0;$i=5.3.x中可用。如果由于任何原因无法安装较新的PHP版本,您可以查看有关如何使Blowfish与较旧的PHP版本一起工作的更多信息。由于PHP5.2中的crypt不支持crypt\u Blowfish,因此它默认将salt解释为crypt\u DES样式的salt。请注意,输出以“$2”开头

这是我第一次在PHP中使用crypt()函数,我不明白为什么它不起作用。我的代码基于本文:

函数blowfishHash($pw){
//生成随机盐
$salt=“$2y$10$”;
对于($i=0;$i<22;$i++){
$salt.=substr(“./abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789”,兰特(0,63),1);
}
$hash=crypt($pw,$salt);
//打印输出到文件
$file=fopen(“debug.txt”,“w+”);
fwrite($file,“\n\n\n”。$pw);
fwrite($file,“\n\n\n”。$salt);
fwrite($file,“\n\n\n”。$hash);
fclose($文件);
返回$hash;
}
我使用示例密码“password”调用了该函数

所得盐为:
$2y$10$NzRQNjTRfP4jXKvb4TCO.G

但密码是
“$2mV0NZp92R3g”
——似乎太短了


有人能帮我找出我做错了什么吗?

正如您在评论中所说的,您使用的是PHP5.2.x


Blowfish实现仅在PHP>=5.3.x中可用。如果由于任何原因无法安装较新的PHP版本,您可以查看有关如何使Blowfish与较旧的PHP版本一起工作的更多信息。

由于PHP5.2中的
crypt
不支持crypt\u Blowfish,因此它默认将salt解释为crypt\u DES样式的salt。请注意,输出以“$2”开头,这是CRYPT_DES从salt输入中选择的两个字符的salt,并放在hash的前面,输出长度与CRYPT_DES的确切输出长度匹配

有趣的是,在支持CRYPT_BLOWFISH的后续PHP版本中,只需将salt截断为两个字符,就可以获得相同的结果。即:

crypt('password', '$2y$10$NzRQNjTRfP4jXKvb4TCO.G')   /* in PHP 5.2 */ 
 ==
crypt('password', '$2')   /* in PHP 5.4 */
理论上,如果在PHP5.2上错误地使用了CRYPT_河豚风格的salt,那么这对于向后兼容性来说可能很有用

这实际上最近让我有点困惑,因为“$”字符不是根据的CRYPT_DES的有效salt输入,它说:

标准的基于DES的哈希,带有字母表“/0-9A-Za-z”中的两个字符salt。在salt中使用无效字符将导致crypt()失败

但是在这里,“$”字符显然被v5.2和v5.4中的
crypt()
接受


如果
crypt
真的像文档中所说的那样返回了一个失败,而不是接受“$”并默认为crypt\u DES,那么它会更清晰、更安全。

这是我的河豚加密函数

<?php
    function bcrypt($input, $salt=null, $rounds=12) {
        if($rounds < 4 || $rounds > 31) $rounds = 12;
        if(is_null($salt)) $salt = sprintf('$2a$%02d$', $rounds).substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
        return crypt($input, $salt);
    }
    $hash = bcrypt('password');
    if($hash = bcrypt('password', $hash)) {
        // password ok
    }

?>

最初只支持用盐以
$2a$
开头的河豚散列

PHP5.3.7中添加了
$2x$
$2y$
河豚模式,以应对潜在的高位攻击

您的PHP5.2.17不支持
$2y$
河豚模式


这就是代码不起作用的原因。

我已经测试了您的示例,它的输出与本文中的输出完全相同。如何输出/调试$password。在网站上?per cli?我刚刚打印到一个文件(我省略了该文件的代码行)。此函数是否需要特定版本的PHP…?您使用的是什么版本?(我使用的是:5.3.10-1ubuntu3.4)在实际计算之前,您似乎正在将散列“打印”到文件中it@Eevee抱歉,问题不在我的源代码中。我最初发布了“打印”,然后决定在后面添加,但放错了位置…user1403777这是否解决了您的问题,不以任何方式响应答案不是stackoverflow上的正确行为方式。。。
<?php
    function bcrypt($input, $salt=null, $rounds=12) {
        if($rounds < 4 || $rounds > 31) $rounds = 12;
        if(is_null($salt)) $salt = sprintf('$2a$%02d$', $rounds).substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
        return crypt($input, $salt);
    }
    $hash = bcrypt('password');
    if($hash = bcrypt('password', $hash)) {
        // password ok
    }

?>