PHP password_verify 假阴性
PHP password_verify false negative
背景 -
我花了大约一个小时浏览各种帖子站点等,以了解为什么我的密码检查功能突然停止工作。
每次我尝试使用它时,它 returns 错误,包括输入的密码正确时。
我已经回显了我的输入和我的散列,两者匹配良好(通过比较 table 中的散列与回显的散列)。
但是,当这些变量通过 password_verify
时,它 returns 100% 的时间都是错误的。
我觉得哪里不对? - 基于 a post from an external site,我认为这是由于我的 hashedPassword
变量被解析的方式所致。当比较两者时,变量类型出了点问题 returns false.
我的代码和数据库是什么样的? -
users
table。包含其他列。
userId | username | password
----------------------------
1 | example | temp1
Class 包含密码检查器功能。 (已修剪掉try/catch)
public function checkPasswordCorrect($username, $password) { // Returns true is the entered password is correct and false if it isn't.
// This creates a mysqli context to run the connection through.
$mysqli = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbPlusPlus);
// If there is an error connecting to the database, it will be printed and the process will close.
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "SELECT password FROM users WHERE username='$username'";
$result = $mysqli->query($sql);
$row = $result->fetch_array(MYSQLI_ASSOC);
$hashedPassword = $row["password"];
$mysqli->close();
echo $password."<br>".$hashedPassword."<br>"; // The input is correct and the hash matches that in the table.
// We return a value of true or false, depending on the outcome of the verification.
if(password_verify($password, $hashedPassword)) {
echo "return true";
return true;
}
else {
echo "return false";
return false;
}
}
通过在使用 password_verify
之前回显 $hashedPassword
,哈希通过手动检查匹配,如下面的输出所示。
temp0022
yTgjJzSaqOB
return false
我在问什么? -
是否有更好的方法来检查密码输入,更具体地说,我从 table 中提取信息的方法(必须有一些更简单的方法来执行此操作)。
变量解析是罪魁祸首吗?是否有任何我未曾见过的与此主题相关的文档或文章?
我知道什么? - 我对 mysqli
的使用令人震惊,我是新手。我也知道那里有类似的答案,但似乎归结为某种语法错误比什么都重要。
感谢您抽出宝贵时间提供帮助! :D
For all of those of you who are worried that I'm going to be hit by SQL injection attacks: I have since modified this example code
massively and am using prepared, statements. Thank you for your
concern :)
检查您的 table 结构。您的散列字段的长度需要为 60(对于 PASSWORD_BCRYPT
)或 255(对于 PASSWORD_DEFAULT
)(ref)以保存整个散列。你从数据库中得到的是 18 个字符长。您可能将其设置为 VARCHAR(18)
,因此在保存时它会被截断,这就是您未获得匹配项的原因。
编辑:增加了 PASSWORD_DEFAULT 算法的长度。谢谢@Don'tPanic。
背景 - 我花了大约一个小时浏览各种帖子站点等,以了解为什么我的密码检查功能突然停止工作。
每次我尝试使用它时,它 returns 错误,包括输入的密码正确时。
我已经回显了我的输入和我的散列,两者匹配良好(通过比较 table 中的散列与回显的散列)。
但是,当这些变量通过 password_verify
时,它 returns 100% 的时间都是错误的。
我觉得哪里不对? - 基于 a post from an external site,我认为这是由于我的 hashedPassword
变量被解析的方式所致。当比较两者时,变量类型出了点问题 returns false.
我的代码和数据库是什么样的? -
users
table。包含其他列。
userId | username | password
----------------------------
1 | example | temp1
Class 包含密码检查器功能。 (已修剪掉try/catch)
public function checkPasswordCorrect($username, $password) { // Returns true is the entered password is correct and false if it isn't.
// This creates a mysqli context to run the connection through.
$mysqli = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbPlusPlus);
// If there is an error connecting to the database, it will be printed and the process will close.
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$sql = "SELECT password FROM users WHERE username='$username'";
$result = $mysqli->query($sql);
$row = $result->fetch_array(MYSQLI_ASSOC);
$hashedPassword = $row["password"];
$mysqli->close();
echo $password."<br>".$hashedPassword."<br>"; // The input is correct and the hash matches that in the table.
// We return a value of true or false, depending on the outcome of the verification.
if(password_verify($password, $hashedPassword)) {
echo "return true";
return true;
}
else {
echo "return false";
return false;
}
}
通过在使用 password_verify
之前回显 $hashedPassword
,哈希通过手动检查匹配,如下面的输出所示。
temp0022
yTgjJzSaqOB
return false
我在问什么? -
是否有更好的方法来检查密码输入,更具体地说,我从 table 中提取信息的方法(必须有一些更简单的方法来执行此操作)。
变量解析是罪魁祸首吗?是否有任何我未曾见过的与此主题相关的文档或文章?
我知道什么? - 我对 mysqli
的使用令人震惊,我是新手。我也知道那里有类似的答案,但似乎归结为某种语法错误比什么都重要。
感谢您抽出宝贵时间提供帮助! :D
For all of those of you who are worried that I'm going to be hit by SQL injection attacks: I have since modified this example code massively and am using prepared, statements. Thank you for your concern :)
检查您的 table 结构。您的散列字段的长度需要为 60(对于 PASSWORD_BCRYPT
)或 255(对于 PASSWORD_DEFAULT
)(ref)以保存整个散列。你从数据库中得到的是 18 个字符长。您可能将其设置为 VARCHAR(18)
,因此在保存时它会被截断,这就是您未获得匹配项的原因。
编辑:增加了 PASSWORD_DEFAULT 算法的长度。谢谢@Don'tPanic。