我几乎逐字逐句地从这里的一些非常有用的答案中删除了这些代码,所以我无法理解错误。
首先,这是我创建用户帐户的功能:
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是一样的。我清楚地看到这里有一个问题,我记录的盐比最后附加到哈希的盐长一个字符,但它是河豚的适当长度,无论如何,使它变得更短一个字符并不是'似乎有所帮助。
我无法弄清楚我在这里做错了什么。任何帮助将不胜感激。
答案 0 :(得分:2)
根据您自己的盐值和密码'argh'
我运行了一个小测试脚本:
$hash = crypt('argh', '$2a$10$BWZAX7wrwQp5iyK4kh6VL5');
// $2a$10$BWZAX7wrwQp5iyK4kh6VLuIzJHihvZTdfpRXNkTPVKkTiGfLDl1RO
var_dump(crypt('argh', $hash) == $hash);
// bool(true)
问题似乎不在您展示的代码中。
您可以检查数据库字段宽度以存储密码哈希值,该哈希值应至少为60宽。当你在它的时候,修复你的SQL注入漏洞(最好使用预准备语句)。