password_verify() 针对 MySQL 不起作用
password_verify() against MySQL doesn't work
我存储密码,通过表单,通过 PDO 进入 MySQL 数据库,在用 password_hash() 散列后
(VARCHAR(512) 字段)
$options = array(
'cost' => 12
);
$password = password_hash($password, PASSWORD_BCRYPT, $options);
假设
$pass = "123Azerty";
//and the hash is
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
当我从数据库中获取密码并使用 password_verify() 对其进行验证时,它 returns 始终为 false
...
...
$returnedPWD = $row['password'];
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
此时,我试过"manually"这样
$pass = "123Azerty";
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
if (password_verify($pass,$hash )){
echo "TRUE";
} else {
echo "FALSE";
}
它总是返回 FALSE
但是
当我改变的时候
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
// into
$hash = 'y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe';
它起作用了。因为用单引号括起来的散列是不可解析的。
据我了解,这意味着从数据库中获取的哈希值被解释为可解析的(双手提包)而不是根本不起作用
然后我尝试将字符串包含在 db int strval():
...
...
$returnedPWD = strval($row['password']);
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
但是它returns总是假的
阅读所有与 password_verify() 无法正常工作相关的帖子,我没有想出任何有效的解决方案。
请问有什么办法可以解决吗?
提前致谢
编辑 1
我确实尝试过 PASSWORD_DEFAULT 的其他设置,但没有任何变化。
我还尝试在数据库存储前对其进行 base64 编码,然后对其进行解码。但什么都没有改变
编辑 2
我使用带参数的 PDO 存储数据
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => "$username",
':password' => "$password" // hashed one
);
编辑 3
Table结构
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(512) NOT NULL,
`enabled` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=13 ;
$username = trim($_POST["username"];
$password = trim($_POST["password"];
// Query to insert data
$query = "INSERT INTO `users` (username, password, enabled) VALUES (:username, :password, 1)";
// The very original setup I did use and didn't work out
$param_password = password_hash($password, PASSWORD_DEFAULT);
// Bind parameters
$params = array(
':username' => "$username",
':password' => "$param_password"
);
...
...
// insert into db
$sth = $sql->prepare($query);
// Call MySQL
try {
$sth->execute($params); // Execute the Query
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
...
...
这里是我如何从数据库中读取的基本内容
...
...
$username_login = trim($_POST["username"]);
$password_login = trim($_POST["password"]);
...
...
$query = "SELECT * FROM `users` WHERE username = :username";
$params = array(
':username' => $username_login
);
$sth = $sql->prepare($query);
try{
$sth->execute($params);
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $key => $value) {
global $$key;
$$key = $value;
}
}
...
...
if (password_verify($password_login, $password) and $enabled == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["logged"] = true;
$_SESSION["id"] = $id;
$_SESSION["uname"] = $username_login_;
// Redirect user to welcome page
header("location: index.php");
} else {
// Display an error message if password is not valid
$password_login__err = "The password you entered was not valid. Or you are not enabled";
}
...
...
您的代码无法运行,因为 "$password "
- 它末尾有 space。应该是:
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => $username,
':password' => $password, // hashed one
);
您的手动测试不起作用,因为
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
有双引号,它插入 y
、</code> 和 <code>$Tz...
作为导致空字符串的变量。这就是单引号起作用的原因。
根据您提供的信息,我构建了有效的示例代码:Check here
我存储密码,通过表单,通过 PDO 进入 MySQL 数据库,在用 password_hash() 散列后 (VARCHAR(512) 字段)
$options = array(
'cost' => 12
);
$password = password_hash($password, PASSWORD_BCRYPT, $options);
假设
$pass = "123Azerty";
//and the hash is
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
当我从数据库中获取密码并使用 password_verify() 对其进行验证时,它 returns 始终为 false
...
...
$returnedPWD = $row['password'];
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
此时,我试过"manually"这样
$pass = "123Azerty";
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
if (password_verify($pass,$hash )){
echo "TRUE";
} else {
echo "FALSE";
}
它总是返回 FALSE
但是
当我改变的时候
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
// into
$hash = 'y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe';
它起作用了。因为用单引号括起来的散列是不可解析的。 据我了解,这意味着从数据库中获取的哈希值被解释为可解析的(双手提包)而不是根本不起作用
然后我尝试将字符串包含在 db int strval():
...
...
$returnedPWD = strval($row['password']);
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
但是它returns总是假的 阅读所有与 password_verify() 无法正常工作相关的帖子,我没有想出任何有效的解决方案。
请问有什么办法可以解决吗?
提前致谢
编辑 1
我确实尝试过 PASSWORD_DEFAULT 的其他设置,但没有任何变化。 我还尝试在数据库存储前对其进行 base64 编码,然后对其进行解码。但什么都没有改变
编辑 2
我使用带参数的 PDO 存储数据
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => "$username",
':password' => "$password" // hashed one
);
编辑 3
Table结构
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(512) NOT NULL,
`enabled` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=13 ;
$username = trim($_POST["username"];
$password = trim($_POST["password"];
// Query to insert data
$query = "INSERT INTO `users` (username, password, enabled) VALUES (:username, :password, 1)";
// The very original setup I did use and didn't work out
$param_password = password_hash($password, PASSWORD_DEFAULT);
// Bind parameters
$params = array(
':username' => "$username",
':password' => "$param_password"
);
...
...
// insert into db
$sth = $sql->prepare($query);
// Call MySQL
try {
$sth->execute($params); // Execute the Query
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
...
...
这里是我如何从数据库中读取的基本内容
...
...
$username_login = trim($_POST["username"]);
$password_login = trim($_POST["password"]);
...
...
$query = "SELECT * FROM `users` WHERE username = :username";
$params = array(
':username' => $username_login
);
$sth = $sql->prepare($query);
try{
$sth->execute($params);
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $key => $value) {
global $$key;
$$key = $value;
}
}
...
...
if (password_verify($password_login, $password) and $enabled == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["logged"] = true;
$_SESSION["id"] = $id;
$_SESSION["uname"] = $username_login_;
// Redirect user to welcome page
header("location: index.php");
} else {
// Display an error message if password is not valid
$password_login__err = "The password you entered was not valid. Or you are not enabled";
}
...
...
您的代码无法运行,因为 "$password "
- 它末尾有 space。应该是:
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => $username,
':password' => $password, // hashed one
);
您的手动测试不起作用,因为
$hash = "y$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
有双引号,它插入 y
、</code> 和 <code>$Tz...
作为导致空字符串的变量。这就是单引号起作用的原因。
根据您提供的信息,我构建了有效的示例代码:Check here