【问题标题】:PHP crypt not matching correctlyPHP crypt没有正确匹配
【发布时间】:2014-09-30 18:37:50
【问题描述】:

我正在尝试使用 PHP crypt() 创建一个基本的密码哈希/验证方案。我现在无法升级到 PHP 5.5.0,所以我不能使用 password_hash() 和 password_verify()。

我的代码如下:

function myinit_salt()
  {
    $options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';

    for ($i = 0; $i <= 20; $i ++) {
      $options = str_shuffle ( $options );
      $salt .= $options [rand ( 0, 63 )];
    }

    return $salt;
  }

...(在注册时加密用户提供的密码)...

$salt = myinit_salt();
$blowfish = '$2a$10$';
$enc_pw = crypt($userinput['password'], $blowfish . $salt);

...(将加密密码存储在数据库中)...

...(在尝试登录时根据用户提供的密码验证存储的密码)...

function verify_password($input_password, $db_password)
  {
    if ($input_password) {
      if (crypt($input_password, $db_password) == $db_password) {
        //authenticated
        return true;
      } else return false;
    } else return false;
  }

即使用户提供的密码匹配,这也会返回 false。所以我让 verify_password() 吐出它正在使用的值,这就是给出的:

用户提供的密码 ($input_password) = abcxyz123

$db_password = $2a$10$y/WXEmlCb6392Wpf8FMpq.FuwwnaSU51x/xPdFYlTl5y6Bsn51Nzi

verify_password() 加密哈希 = $2a$10$y/WXEmlCb6392Wpf8FMpq.s8Y6lrJGDMOAJ4d8GffQUEiAWKsEyqS

所以看起来盐匹配,但密码哈希由于某种原因不匹配。

谁能解释一下?谢谢。

【问题讨论】:

    标签: php passwords crypt


    【解决方案1】:

    您的myinit_salt 中有两个错误

    function myinit_salt()
      {
        $options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
        $salt = ''; // without it notice would be raised
                         // v
        for ($i = 0; $i <= 21; $i ++) {             // <--- length of salt should be 22
                         // ^ 
          $options = str_shuffle ( $options );
          $salt .= $options [rand ( 0, 63 )];
        }
    
        return $salt;
      }
    

    http://php.net/manual/en/function.crypt.php

    附:为什么不用password php 扩展?

    附言不要创建自己的盐生成函数。 str_shuffle - 对 crypt 函数不安全。 mt_rand 也是。最好在已经实现盐生成的地方使用密码扩展。

    【讨论】:

      【解决方案2】:

      verify_password() 函数中生成的哈希值生成一个有效的 BCrypt 哈希,其参数和盐值与存储的哈希值相同。这实际上只剩下另一种选择,即输入不同$userinput['password'] != $input_password

      无论如何,您很有可能可以使用新的 password_hash() 函数,我建议您这样做。有一个compatibility pack 可用于 PHP 版本 5.3.7 及更高版本。即使是 5.3,也可以稍加改动即可使用它。

      【讨论】:

        猜你喜欢
        • 2016-05-02
        • 2011-01-15
        • 2016-03-23
        • 2021-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-27
        • 2014-04-08
        相关资源
        最近更新 更多