我有一个问题与下面的代码。它从这里被拉出来,并稍加修改,以包括验证,并在提交适当的表单并通过验证时触发。问题是密码的散列。
散列密码与数据库中的密码不匹配,即使密码本身和盐是相同的。我已经根据写入数据库的内容检查了$ hashhed_password变量。它们很相配。在登录端,盐是匹配的,但是当使用相同的密码时,盐后面的部分是不一样的?结果如下所示:
2美元05 Bj79bEbmWG9GeMbBAIXID.zMtNecb3B5qWkiGZrSccWcefQG7IXUy美元2美元05 Bj79bEbmWG9GeMbBAIXID.6qNLDcZ21XAKoSOIriqTxlAUjjTygoy美元
用户名或密码有问题。
除非我错过了一些明显的东西,我唯一能想象的是在登录上使用不同的算法,但我不知道如何确认或纠正。如有任何帮助,不胜感激。
<?php
$password = mysql_real_escape_string($_POST['password']);
$username = mysql_real_escape_string($_POST['username']);
//This string tells crypt to use blowfish for 5 rounds.
$Blowfish_Pre = '$2a$05$';
$Blowfish_End = '$';
// // PHP code you need to register a user
if($_SERVER['REQUEST_METHOD'] == "POST" && isset($_POST['register'])) {
global $valid;
user_reg_validate($con, $_POST['username'], $_POST['email'], $_POST['password'], $_POST ['password2']);
if ($valid != false) {
// Blowfish accepts these characters for salts.
$Allowed_Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
$Chars_Len = 63;
// 18 would be secure as well.
$Salt_Length = 21;
$mysql_date = date( 'Y-m-d' );
$salt = "";
for($i=0; $i<$Salt_Length; $i++) {
$salt .= $Allowed_Chars[mt_rand(0,$Chars_Len)];
}
$bcrypt_salt = $Blowfish_Pre . $salt . $Blowfish_End;
$hashed_password = crypt($password, $bcrypt_salt);
$sql = "INSERT INTO login (username, salt, password) VALUES ('$username', '$salt', '$hashed_password')";
mysqli_query($con, $sql) or die( mysql_error() );
}
}
if($_SERVER['REQUEST_METHOD'] == "POST" && isset($_POST['login'])) {
global $valid;
user_login_validate($con, $_POST['username'], $_POST['password']);
if($valid != false) {
// Now to verify a user’s password
$sql = "SELECT salt, password FROM login WHERE username='$username'";
$result = mysqli_query($con, $sql) or die( mysql_error() );
$row = mysqli_fetch_assoc($result);
$hashed_pass = crypt($password, $Blowfish_Pre . $row['salt'] . $Blowfish_End);
echo $hashed_pass . "</br>";
echo $row['password'] . "</br>";
if ($hashed_pass == $row['password']) {
echo 'Password verified!';
} else {
echo 'There was a problem with your user name or password.';
}
}
}
?>
您可以免费使用相同的功能,只需使用password_hash()。该函数将生成一个加密安全的盐,并使其成为哈希值的一部分,因此不需要单独的数据库字段。它还使用$2y
签名,并为cost参数添加一个合理的默认值(5非常低)。
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// 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);
还要注意,您的代码没有针对sql注入的保护。尽快切换到预处理语句,编写代码将变得比构建查询更容易,而且mysql和PDO都支持它。