2014-02-13 8 views
0

Я пытался сопоставить хешированный пароль из базы данных с паролем - hashed из формы входа и не соответствует ни на что.Laravel 4.1 Hash :: make inconsistency

Затем я провел несколько тестов на согласованность.

$password = Hash::make('secret'); 
echo $password; 

Я получаю разные результаты каждый раз, когда обновляю страницу. Не похоже на md5, это непротиворечиво.

Я что-то упустил?

Или я использую/делаю это неправильно?

Почему Hash :: make производит несогласованный результат с теми же аргументами?

ответ

2

Это правильно, и это по дизайну.

AFAIK, функция использует функцию password_hash() PHP, и по умолчанию флага PASSWORD_BCRYPT, который

PASSWORD_BCRYPT - использовать алгоритм CRYPT_BLOWFISH для создания хэша. Это приведет к созданию стандартного хеша crypt(), использующего идентификатор «$ 2y $». Результат всегда будет состоять из 60 символов, или FALSE при сбое.

Это означает, что соль автоматически генерируется при каждом вызове, и вставляется в пределах сгенерированной строку, которая содержит: идентификатор алгоритма (в данном случае, $2y$) стоимость итерации (по умолчанию 12) , хешированный пароль и генерируемая случайная соль.

Это означает, что каждый раз, когда вы используете свой пароль, создается новая соль, поэтому строка всегда будет отличаться - даже если пароль тот же. Это один сильных сторон над простым хешем md5 без соли.

Чтобы проверить это, вы используете Hash :: check(), в котором используется функция php-пароля password_verify(), которая анализирует хеш, угадывает используемый алгоритм, принимает, встроенную соль и поэтому может проверить, при одинаковых начальных условиях, создает идентичный хэш.

Редактировать

В самом деле, это метод (в Illuminate/Hashing/BcryptHasher)

* Hash the given value. 
* 
* @param string $value 
* @param array $options 
* @return string 
*/ 
public function make($value, array $options = array()) 
{ 
    $cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds; 

    $hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => $cost)); 

    if ($hash === false) 
    { 
     throw new \RuntimeException("Bcrypt hashing not supported."); 
    } 

    return $hash; 
} 
+0

Хммм. Отличная информация. Итак, как я могу сравнить хешированный пароль на уровне sql? Единственное решение, которое я вижу, это получить пароль (запрос), а затем использовать Hash :: check ..., чтобы получить пароль, нужно найти запись, которая соответствует имени пользователя. но я хочу два поиска столбца/совпадения по моему запросу. – Craftein

+1

Я не думаю, что вы можете сделать это на уровне БД, или это было бы довольно халатно и сложно - обычно это делается на уровне обработки, я не вижу причин, чтобы избежать этого –

0
Validator::extend('old_password', function($attribute, $value, $parameters) { 
    return Hash::check($value, Auth::user()->password); 
}); 

$rules = array(
    'old_password' => 'required|old_password', 
    'new_password' => 'required|confirmed' 
); 
$messages = array(
    'old_password' => 'wrong old password' 
); 
$validator = Validator::make($data = $input, $rules, $messages); 
Смежные вопросы