我想我直接从mysql数据库使用函数PASSWORD
散列密码(我在这里做错了吗?)。我正在尝试使用此代码验证密码:
if($submit)
{
$first=$_POST['first'];
$password=$_POST['password'];
$hash="*85955899FF0A8CDC2CC36745267ABA38EAD1D28"; //this is the hashed password i got by using function PASSWORD in database
$password=password_verify($password,$hash);
$db = new mysqli("localhost", "root","","learndb");
$sql = "select * from admin where username = '" . $first . "' and password = '". $password . "'";
$result = $db->query($sql);
$result=mysqli_num_rows($result);
if($result>0)
{
session_start();
$_SESSION['logged_in'] = true;
session_regenerate_id(true);
header("Location:loginhome.php");
}
}
但密码不匹配。我在这里缺少什么?
更新:
在完成所有建议之后,我使用了来自php代码的password_hash
来存储到数据库中。
$db = new mysqli("localhost", "root","","learndb");
$password=password_hash('ChRisJoRdAn123',PASSWORD_DEFAULT);
$sql="INSERT INTO admin (username,password)values('ChrisJordan','$password')";
$db->query($sql);
密码仍不匹配。
答案 0 :(得分:2)
无法在数据库中搜索salted密码哈希。要计算哈希值,您需要使用password_hash()函数,就像在insert语句中已正确执行一样。
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
要检查密码,首先需要按用户名搜索(使用准备好的查询来避免sql注入):
$sql = 'select * from admin where username = ?';
$db->prepare($sql);
$db->bind_param('s', $first);
当您最终从数据库中获取存储的哈希时,可以像这样检查:
// 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 :(得分:2)
评论太长了。
看到此问题尚未在任何答案旁边包含绿色勾号,我提交以下内容以指出可能的问题。
我注意到您正试图从MD5迁移到password_hash()
- password_verify()
。
您需要知道的是,MD5产生的是32个字符长度的字符串,而password_hash()
的长度为60个字符串。
varchar(255)
。如果您将密码列的长度保持为32,那么您需要清除该列中的现有哈希值,然后按照手册建议的那样将列更改为60或255。
您需要清除所有现有密码,更改列,创建新哈希,然后再次尝试登录代码。
我在你的代码中看到了这一点:
"*85955899FF0A8CDC2CC36745267ABA38EAD1D28"; //this is the hashed password i got by using function PASSWORD in database
此字符串*85955899FF0A8CDC2CC36745267ABA38EAD1D28
长40,太短而且已被切断。
这告诉我你的列的长度是40,而不是60,或者如手册所示,再次为255。
MD5参考:
将哈希值作为32个字符的十六进制数返回。
password_hash()
的参考:
结果将始终为60个字符的字符串,或者在失败时为FALSE。
要更改列,请参阅以下链接:
还要确保您的表单包含POST方法,并且输入具有匹配的名称属性,并且不会引入任何空格。
您可以使用trim()
来摆脱这些。
将error reporting添加到文件的顶部,这有助于查找错误。
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code
旁注:只应在暂存时进行显示错误,而不是生产。
以及or die(mysqli_error($db))
到mysqli_query()
。
修改:
你需要做的是获取一个数组并获得匹配。
$sql = "select * from admin where username = '".$first."' and password = '".$password."' ";
$result = $db->query($sql);
if ($result->num_rows === 1) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if (password_verify($password, $row['password'])) {
//Password matches, so create the session
// $_SESSION['user']['user_id'] = $row['user_id'];
// header("Location:/members");
echo "Match";
}else{
echo "The username or password do not match";
}
}
另一种可能的解决方案:
$query = "SELECT * from admin WHERE username='$first'";
$result = $db->query($query);
if($result->num_rows ===1){
$row = $result->fetch_array(MYSQLI_ASSOC);
if (password_verify($password, $row['password'])){
echo "match";
} else {
$error = "email or Password is invalid";
echo $error;
}
}
mysqli_close($db); // Closing Connection
答案 2 :(得分:1)
您必须使用password_hash
对使用password_verify
验证的密码进行编码。
MySQL函数PASSWORD
完全不同。它用于编码特定于MySQL身份验证的密码。 (MySQL明确建议不要使用PASSWORD
进行其他而不是MySQL身份验证。)
两者使用不同的散列算法,以不同的格式显示其输出,并且通常彼此不兼容。
<小时/> 使用
password_hash
和password_verify
的典型方法是:
$hash = password_hash($password, PASSWORD_DEFAULT);
//Store $hash in your database as the user's password
//To verify:
//Retrieve $hash from the database, given a username
$valid = password_validate($password, $hash);
您的代码中的问题是您正在执行此操作:
$password=password_verify($password,$hash); $sql = "select * from admin where username = '" . $first . "' and password = '". $password . "'";
password_verify
返回一个布尔值(密码和散列匹配)。相反,您需要从数据库中检索哈希值,并将输入的密码与该哈希值匹配。
答案 3 :(得分:1)
password_verify
是一个布尔函数,返回true
或false
。在您的代码中,从Post param获取密码值后,您执行此操作
$password=password_verify($password,$hash);
将$password
值更改为true
或false
,并将您在mysql select语句中使用的$password
中存储的布尔值
$sql = "select * from admin where username = '" . $first . "' and password = '". $password . "'";
另一件事:您使用的散列/加密密码可能不是您正在使用的密码的正确哈希值。
更新:试试这个
$cost = [
'cost' => 15,
];
$hash_password = password_hash('ChRisJoRdAn123', PASSWORD_BCRYPT, $cost);
在任何数据库操作之前,将password
字段varchar
长度更改为&gt; = 64
$sql = "INSERT INTO admin (username,password)values('ChrisJordan','".$hash_password."')";
插入操作后,使用用户
执行select语句$sql = "select * from admin where username = 'ChrisJordan'";
从 post参数获取hased password
和password
后,您需要使用password_verify
验证这两个密码
if (password_verify(validate($_POST['password']), $hash_password_from_db)) {
echo "Valid Password";
}else{
echo "Invalid Password";
}