这个基于crypt()的bcrypt身份验证我做错了什么?

时间:2012-12-12 22:18:02

标签: php bcrypt crypt

我几乎逐字逐句地从这里的一些非常有用的答案中删除了这些代码,所以我无法理解错误。

首先,这是我创建用户帐户的功能:

function BFcrypt($password,$cost)
{
    $chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt=sprintf('$2a$%02d$',$cost);
    for($i=0;$i<22;$i++) $salt.=$chars[rand(0,63)];
    return array(
            'salt'=>$salt,
            'hash'=>crypt($password,$salt)
            );
}

然后,当用户登录时:

case 'login':
    $login  =$_POST['login'];
    $pwd    =$_POST['pwd'];
    $sql    ="SELECT * FROM `users` WHERE `users`.`login`='$login' LIMIT 1;";
    if($query = mysql_query($sql)){
            $row=mysql_fetch_assoc($query);
            print_r($_POST);
            print_r($row);
            $hash = $row['password'];
            if(crypt($pwd,$hash)==$hash){
                echo"SUCCESS";
            }else{
                echo"FAILURE";

            }
    }

登录功能似乎总是失败。我已经设置它显示$ pwd,$ hash和crypt($ pwd,$ hash),并且由于某种原因,crypt($ pwd,$ hash)似乎永远不会== $ hash。

这是示例用户的数据库中的一行(我现在正在记录盐,但我知道它应该包含在哈希中:

'id'=>'680',
'login'=>'argh',
'password'=>'$2a$10$BWZAX7wrwQp5iyK4kh6VLunqy82eiXg7GaDs6mJLqdgT5s2qiUqYW',
'salt'=>'$2a$10$BWZAX7wrwQp5iyK4kh6VL5',
'first'=>'argh',
'last'=>'argh',
'zip'=>'00000',
'email'=>'argh',
'date updated'=>'2012-12-12 16:05:29'

我相信当我调用crypt($ pwd,$ hash)时,它会截断$ hash,只留下原始的22个字符的salt(加上前缀),因此输出将与$ hash相同,只要$ pwd是一样的。我清楚地看到这里有一个问题,我记录的盐比最后附加到哈希的盐长一个字符,但它是河豚的适当长度,无论如何,使它变得更短一个字符并不是'似乎有所帮助。

我无法弄清楚我在这里做错了什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

根据您自己的盐值和密码'argh'我运行了一个小测试脚本:

$hash = crypt('argh', '$2a$10$BWZAX7wrwQp5iyK4kh6VL5');
// $2a$10$BWZAX7wrwQp5iyK4kh6VLuIzJHihvZTdfpRXNkTPVKkTiGfLDl1RO

var_dump(crypt('argh', $hash) == $hash);
// bool(true)

问题似乎不在您展示的代码中。

您可以检查数据库字段宽度以存储密码哈希值,该哈希值应至少为60宽。当你在它的时候,修复你的SQL注入漏洞(最好使用预准备语句)。