作为学习php的一部分,我想尝试一个注册和登录页面,但是,我正在关注如何存储密码的site使用MySQLI而我没有使用它:
哈希密码
$password1 = 'hello123';
// A higher "cost" is more secure but consumes more processing power
$cost = 10;
// Create a random salt
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
// Prefix information about the hash so PHP knows how to verify it later.
// "$2a$" Means we're using the Blowfish algorithm. The following two digits are the cost parameter.
$salt = sprintf("$2a$%02d$", $cost) . $salt;
// Value:
// $2a$10$eImiTXuWVxfM37uY4JANjQ==
// Hash the password with the salt
$hash = crypt($password1, $salt);
我坚持要检索密码,但这是网站的代码:
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$sth = $dbh->prepare('
SELECT
hash
FROM users
WHERE
username = :username
LIMIT 1
');
$sth->bindParam(':username', $username);
$sth->execute();
$user = $sth->fetch(PDO::FETCH_OBJ);
// Hashing the password with its hash as the salt returns the same hash
if ( crypt($password, $user->hash) === $user->hash ) {
// Ok!
}
从我所看到的,他在数据库中获取用户密码的哈希值,并将使用哈希和检查传递的密码与数据库中的密码进行比较。
我一直在尝试这个,但结果哈希与原始哈希不一样:
$pwdtocheck = 'hello123';
// no call do DB yet, doing this on the same page after hashing, the $hash is the same as above
$pwdhash = crypt($pwdtocheck, $hash);
// if I echo $pwdhash it's never exactly the same as the $hash.
if ( $pwdhash === $hash) {
echo "same pwd";
}
答案 0 :(得分:2)
我无法在代码中看到实际问题,也许您的数据库字段小于60个字符,或者您正在比较不同的密码。在每种情况下,都有一种更简单,更安全的哈希密码方法,只需使用新功能password_hash()和password_verify()。早期的PHP版本也存在compatibility pack。
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
答案 1 :(得分:1)
编辑:
我现在看到,当您比较密码时, 使用盐。在你的行中:
$pwdhash = crypt($pwdtocheck, $hash);
$hash
变量之前加上了盐,因为crypt()
会自动为您执行此操作。 crypt()
将从$hash
中提取盐,因为它根据所使用的算法知道盐的预期长度。 See the documentation
我将在下面保留我原来的答案,以及那些寻找类似答案的人。
结束编辑
密码对您来说并不相同,因为当您最初散列密码以放入数据库时使用salt
,但是在检查数据库时您没有使用密码。
保存密码时应使用相同的salt字符串,就像在登录时检查用户密码一样。通常,您将为每个密码随机生成salt字符串(正如您所做的那样),然后将salt字符串与散列密码(在同一列或其自己的列中)一起保存到数据库中,以便您可以使用相同的在登录时检查用户密码的盐。
答案 2 :(得分:0)
我无法访问您引用的文章,但我想:
你需要检查使用salt作为salt而不是hash。
crypt($pwdtocheck, $user->salt) == $user->hash
应该有效