Итак, после ввода пароля в моей базе данных
(пароль столбца типа бинарный (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 ""
Я ищу несколько часов, но я не нашел решения.
На основании документации для Двоичный тип данных в 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 байт).
Других решений пока нет …