2

我已经从 SO 上的一堆非常有用的答案中逐字逐句地抄写了这段代码,所以我无法理解出了什么问题。

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

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 个字符的盐(加前缀),因此只要 $pwd 是相同的。我清楚地看到这里有一个问题,我正在记录的盐比最终附加到散列的盐长一个字符,但它是河豚的合适长度,无论如何,让它短一个字符不会'似乎没有帮助。

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

4

1 回答 1

2

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

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

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

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

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

于 2012-12-13T08:52:42.347 回答