PHP password_verify 似乎使用一个字符串而不是另一个被认为相等的字符串

标签 php mysql hash passwords password-encryption

我将用户名和加密密码存储在 mysql 数据库中。仅出于测试目的,我还将密码以未加密的形式存储在数据库中。

在下面的代码中,我从数据库中获取散列密码和未加密密码。然后我加密未加密的密码。

给定的密码未通过存储哈希或新哈希的密码验证测试。

存储的密码确实通过了存储哈希和新哈希的密码验证测试。

对 strcmp 的调用表示存储的密码和给定的密码相等。

这怎么可能?

[edit] :我正在从网页上的用户输入中传递 $password。

// get hashed password from database
$sql = "SELECT member_password FROM member WHERE member_username=:username;";
$stmt = $db->prepare($sql);
$stmt->bindParam("username", $username);
$stmt->execute();
$hash = $stmt->fetch(PDO::FETCH_ASSOC);
$hash = $hash["member_password"];

// get unencrypated password from database
$sql = "SELECT member_unencrypted FROM member WHERE member_username=:username;";
$db = getConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam("username", $username);
$stmt->execute();
$unencrypted = $stmt->fetch(PDO::FETCH_ASSOC);
$unencrypted = $unencrypted["member_unencrypted"];

// encrypt the unencrypted password that was retrieved from the database
$encrypted = password_hash($unencrypted, PASSWORD_DEFAULT);

// given password does not pass the new hash per this test
if(password_verify($password, $encrypted))
  echo '<br>given password passed new hash';
else 
  echo '<br>given password did not pass new hash';

// stored password does pass the new hash per this test
if(password_verify($unencrypted, $encrypted))
  echo '<br>stored password passed new hash';
else
  echo '<br>stored password did not pass new hash';

// given password does not pass the stored hash per this test.
if(password_verify($password, $hash)){
  echo '<br>given password passed stored hash';
else
  echo '<br>given password did not pass stored hash';

// stored password does pass the stored hash per this test.
if(password_verify($unencrypted, $hash))
  echo '<br>stored password passed stored hash';
else
  echo '<br>stored password did not pass stored hash';

// stored and given passwords are equal per this test.
if(strcmp($unencrypted, $password)) 
  echo '<br>stored and given passwords are equal';
else
  echo '<br>stored and given passwords are not equal';

输出:

given password did not pass new hash
stored password passed new hash
given password did not pass stored hash
stored password passed stored hash
stored and given passwords are equal

最佳答案

从您的问题中不清楚变量 $password 的来源,以及它是否包含与数据库中存储的文本相同的文本。

如果您进行此类测试,您必须知道函数 password_hash() 将生成一个唯一的盐并将其包含在生成的哈希中。为了进行验证,您需要此盐(和其他参数)来获得可比较的哈希值。这意味着哈希每次都会不同,如果您调用 password_hash() 两次,您最终会得到不同的盐和不可比较的哈希。

我试图在另一个 answer 中解释哈希格式.

[Bruce 编辑:查看评论以获得答案]

关于PHP password_verify 似乎使用一个字符串而不是另一个被认为相等的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26030349/

相关文章:

javascript - 如何在coffeescript中将两个数组压缩到一个对象中?

java - 根据 HashMap 检查字符串

javascript - JQuery 函数submit(),用于当用户在 input=text 中按 Enter 时,还提交位于同一表单中的 input=submit

php - 无法创建 MongoDb 客户端对象! [未找到类 'MongoDB\Client']

mysql - SQL 对于每个语句

mysql - rails/mysql - 我如何消除 ActiveRecord::StatementInvalid 错误?

java - 如何将字符串存储到 HashMap /哈希表中?

php - 禁止跨域飞行前选项

php - 通过流访问大对象 (LONGBLOB)

mysql - 将数据从 latin1 更改为 utf8