password_verify возвращает false, если я получаю хэш из базы данных, но возвращает true, если я копирую и вставляю его

Итак, после ввода пароля в моей базе данных
(пароль столбца типа бинарный (255))

//let's say his username is on $username and password in $password
$password = "abc123";
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "INSERT INTO users(username, password) VALUES(:usr,:psw)";
$stmt->bindValue( "usr", $username, PDO::PARAM_STR );
$newpsw = password_hash ( $password , PASSWORD_DEFAULT);
$stmt->bindValue( "psw", $newpsw, PDO::PARAM_STR );
$stmt->execute();

через CMD я иду в базу данных, и я вижу, что пароль это

$2y$10$nDzlRwWfC9sTvVqv5f7G1eByHethRHjEWGwBOjkpoaq3y2Fb.LCC.

Теперь, когда пользователь входит в систему, я успешно извлекаю его пароль из базы данных.

//let's say his username is on $username and password in $password
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "SELECT password FROM users WHERE username = :usr LIMIT 1";
$stmt = $con->prepare( $sql );
$stmt->bindValue( "usr", $username, PDO::PARAM_STR );
$stmt->execute();
$result = $stmt->fetch();
$psw_from_db = $result["password"]; //checked with echo and it's correct

Если я сделаю

password_verify($password , $psw_from_db);

он вернет false, хотя я проверил и $ password и $ psw_from_db
и они имеют правильные значения внутри.

Если я скопирую пароль непосредственно из базы данных и поместу его вместо $ psw_from_db, он вернет true

password_verify($password ,'$2y$10$nDzlRwWfC9sTvVqv5f7G1eByHethRHjEWGwBOjkpoaq3y2Fb.LCC.');
//'' have to be used, it won't work with ""

Я ищу несколько часов, но я не нашел решения.

1

Решение

На основании документации для Двоичный тип данных в MySQL, кажется, что ответ, который вы получаете, правильно дополнен \0 (нулевой символ):

когда BINARY значения сохраняются, они дополняются правой кнопкой
значение до указанной длины. Значение пэда 0x00 (ноль
байт). Значения добавляются справа 0x00 на вставке, и не заканчивается
байты удаляются при выборе. Все байты значимы в сравнении,
включая операции ORDER BY и DISTINCT. 0x00 байты и пробелы
отличаются в сравнении, с 0x00 < пространство.

Таким образом, когда вы извлекаете пароль из базы данных, вы на самом деле получаете строку длиной 255 (вот почему я попросил var_dump в мой комментарий, и не echo). Проверяя несколько значений локально, я получил что-то вроде:

string(255) "$2y$10$L5C66A5xFvf1YYAoWbnQDuRyveVOrnz1jfV/Eb0kT9UkZlWzCfK8a"string(255) "$2y$10$EAkfkh8S1m66FWAX/KZYMeuhteDREL5B22cgLP0feKZ9.ydMgcgpa"string(255) "$2y$10$Ll/272JbvIilDj74FAqVIeckWUGezqT926Z1LkVBZZSVwTaFUGOLe"string(255) "$2y$10$fxvZv2ya0RncOksp09vqjekIWNmdEX9fEUahU6puSe8HqGcY51re6"string(255) "$2y$10$f1xDu3fFnqMw.MEa4.93Tu3ouhr3kmXXbe41oTyy8xGTKaRbafQ8G"string(255) "$2y$10$YhjBmNFjL7a8lj1Soyvdhe9GpfQ7SsX.dfkI0keQ0IgrkKIfQQjpC"

Ты можешь использовать trim или измените тип данных из BINARY(255) в BINARY(60) или же CHAR(60) BINARY или даже CHAR(60) с latin1 сверка. (хэши bcrypt составляют 59-60 байт).

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector