PHP crypt()Blowfish功能不起作用

时间:2013-01-15 03:08:58

标签: php bcrypt blowfish crypt

这是我第一次在PHP中使用crypt()函数,但我无法弄清楚它为什么不起作用。我的代码基于这篇文章:http://www.techrepublic.com/blog/australia/securing-passwords-with-blowfish/1274

function blowfishHash ($pw) {
   //generate random salt
   $salt = "$2y$10$";
   for ($i = 0; $i < 22; $i++) {
       $salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
   }
  $hash = crypt($pw, $salt);

  //printout to file
  $file = fopen("debug.txt", "w+");
  fwrite($file, "\n\n\n".$pw);
  fwrite($file, "\n\n\n".$salt);
  fwrite($file, "\n\n\n".$hash);
  fclose($file);

  return $hash;
}

我使用示例密码&#34;密码&#34;调用了该函数。

所得盐为:$2y$10$NzRQNjTRfP4jXKvb4TCO.G
但密码是"$2mV0NZp92R3g" - 这似乎太短了。

有人可以帮我弄清楚我做错了吗?

4 个答案:

答案 0 :(得分:2)

正如您在评论中所述,您使用的是PHP 5.2.x。

Blowfish实现仅适用于PHP&gt; = 5.3.x.如果出于任何原因无法安装较新的PHP版本,您可以查看here有关如何使Blowfish与旧版PHP一起使用的更多信息。

答案 1 :(得分:1)

由于PHP 5.2中的crypt不支持CRYPT_BLOWFISH,因此默认将salt解释为CRYPT_DES样式的salt。请注意,输出以“$ 2”开头,这是CRYPT_DES从salt输入中选择并添加到散列前的两个字符的盐,输出长度与精确的CRYPT_DES输出长度匹配。

有趣的是,通过简单地将salt截断为两个字符,您可以在以后支持CRYPT_BLOWFISH的PHP版本中获得相同的结果。即:

crypt('password', '$2y$10$NzRQNjTRfP4jXKvb4TCO.G')   /* in PHP 5.2 */ 
 ==
crypt('password', '$2')   /* in PHP 5.4 */

理论上,如果在PHP 5.2上错误地使用CRYPT_BLOWFISH样式的盐,这可能会对后向兼容性派上用场。

这实际上引起了我最近的一些困惑,因为根据PHP crypt documentation,“$”字符不是CRYPT_DES的有效盐输入,其中说:

  

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

但是这里的“$”字符似乎在v5.2和v5.4中被crypt()接受。

如果crypt实际上像文档所说的那样失败了,而不是接受“$”并默认为CRYPT_DES,那将会更加清晰和安全。

答案 2 :(得分:1)

这是我的河豚加密功能....

<?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
    }

?>

答案 3 :(得分:0)

最初只支持使用以$2a$开头的盐进行河豚散打。

在PHP 5.3.7中添加了

$2x$$2y$ Blowfish模式来处理潜在的高位攻击。

您的PHP 5.2.17不支持$2y$ Blowfish模式。

这就是您的代码无效的原因。