Что я делаю не так с этой аутентификацией bcrypt на основе crypt()?
Я написал этот код почти дословно из множества очень полезных ответов здесь, на 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-символьную соль (плюс префикс), таким образом, результат будет таким же, как у $ hash, пока $ pwd является так же. Я ясно вижу, что здесь есть проблема в том, что соль, которую я записываю, на один символ длиннее, чем та, которая в итоге добавляется к хешу, но это подходящая длина для blowfish, и, в любом случае, сделать ее на один символ короче не так. кажется, чтобы помочь.
Я не могу понять, что я делаю здесь не так. Любая помощь будет оценена.
1 ответ
На основании вашей собственной соли и пароля 'argh'
Я запустил небольшой тестовый скрипт:
$hash = crypt('argh', '$2a$10$BWZAX7wrwQp5iyK4kh6VL5');
// $2a$10$BWZAX7wrwQp5iyK4kh6VLuIzJHihvZTdfpRXNkTPVKkTiGfLDl1RO
var_dump(crypt('argh', $hash) == $hash);
// bool(true)
Кажется, проблема не в коде, который вы показали.
Вы можете проверить ширину поля базы данных, чтобы сохранить хэш пароля, который должен быть не менее 60. И пока вы работаете над этим, исправьте уязвимость SQL-инъекций (лучше всего использовать подготовленные операторы).