php 如何根据数据库验证密码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30345945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:44:08  来源:igfitidea点击:

How to verify password against database?

phphash

提问by sherly

I went through many articles related to this topic, such as this:

我浏览了许多与此主题相关的文章,例如:

Using PHP 5.5's password_hash and password_verify function

使用 PHP 5.5 的 password_hash 和 password_verify 函数

Yet, I'm unsure if I'm hashing and salting the correct way or over doing it!

然而,我不确定我是在以正确的方式进行散列和加盐,还是做得太过分了!

I want to use my own salt and then hash. Both salt and hashed password stored in the database in two different fields.

我想用我自己的盐然后散列。盐和散列密码都存储在数据库中的两个不同字段中。

This is how I hash the password before storing into database

这就是我在存储到数据库之前对密码进行哈希处理的方式

$cost = 10;
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
$salt = sprintf("a$%02d$", $cost) . $salt;

//shall I remove this line and replace below PASSWORD_DEFAULT  with PASSWORD_BCRYPT instead?
$password = crypt($data['password'], $salt);

$hash = password_hash($password, PASSWORD_DEFAULT);

Given that, I'm trying to verify the password as below: Somehow I feel that I'm complicating the process.

鉴于此,我正在尝试验证密码如下: 不知何故,我觉得我正在使这个过程复杂化。

$salt=$row['salt'];//taken from db
$hashAndSalt=$row['hashpword'];//taken from db
$password="pwtester";//user keyed in password

$newpassword = crypt($password, $salt);
$newhash = password_hash($newpassword, PASSWORD_DEFAULT);


if (password_verify($password, $newhash)) {
   echo"verified";
}
else
{
    echo"Not verified"; 
}

EDITED:

编辑:

Now I store like this:

现在我这样存储:

$cost = 10;
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
$options = array('cost' => $cost,'salt' => $salt);
$hash = password_hash($data['password'], PASSWORD_DEFAULT,$options);

But verification confusing:

但验证令人困惑:

$email = "[email protected]";
$uid= '555ca83664caf';
$sql = "SELECT *FROM authsessions WHERE email =:myemail AND useruuid =:uid";

$statement = $pdo->prepare($sql);
$statement->bindValue(':myemail', $email);
$statement->bindValue(':uid', $uid);
$statement->execute();
while( $row = $statement->fetch()) {
    echo "salt ".$row['salt']."<br/><br/>";
    echo "hashpassword ".$row['hashpword'];
}

$salt=$row['salt'];
$hashAndSalt=$row['hashpword'];
$password="test55";

$newhash = password_hash($password+$salt, PASSWORD_DEFAULT);


if (password_verify($newhash, $hashAndSalt)) {
   echo"verified";
}
else
{
    echo"Not verified"; 
}

It echoes "Not Verified"

它与“未验证”相呼应

回答by martinstoeckli

The function password_hash()is just a wrapper, internally it generates a cryptographically safe salt and then calls the crypt()function to calculate the BCrypt hash.

函数password_hash()只是一个包装器,它在内部生成一个加密安全的盐,然后调用该crypt()函数来计算 BCrypt 哈希。

So there is no reason to do the same steps yourself (do not call crypt() and do not generate a salt). Generating your own salt is not recommended, because you cannot do it better than the password_hash function does. Also there is no reason to store the salt in a separate db column, it is already part of the resulting hash-value.

所以没有理由自己做同样的步骤(不要调用 crypt() 也不要生成盐)。不建议生成您自己的盐,因为您不能比 password_hash 函数做得更好。也没有理由将盐存储在单独的 db 列中,它已经是结果哈希值的一部分。

// 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);

回答by Zast

This will verify correctly, as it should.

这将正确验证,因为它应该。

//on creating an account, a user enters a password!
$password="pwtester";//user keyed in password

$newhash = password_hash($password, PASSWORD_DEFAULT);
//#newhash now has the only value that you need to store in the db
//you do not need any more than this value, that you retrieve when you 
//want to verify your password!

//this part is only done to verify passwords!
if (password_verify($password, $newhash)) {
    echo"verified";
}
else
{
    echo"Not verified"; 
}

So provided you have stored the hash in the db

因此,只要您已将哈希存储在数据库中

$newhash=$row['hashpword'];//taken from db
$password="pwtester";//user keyed in password

if (password_verify($password, $newhash)) {
    echo"verified";
}
else
{
    echo"Not verified"; 
}

Should work!

应该管用!

回答by sherly

Password storage:

密码存储:

$cost = 10;

$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');

$options = array('cost' => $cost,'salt' => $salt); 

$hash = password_hash($data['password'], PASSWORD_DEFAULT,$options);

password verify:

密码验证:

<?php
include('config.php');
$email = "[email protected]";
$uid= '555cb0a63f08d';
$sql = "SELECT *FROM authsessions WHERE  useruuid =:uid";

$statement = $pdo->prepare($sql);
$statement->bindValue(':uid', $uid);
$statement->execute();
while( $row = $statement->fetch()) {
echo "salt ".$salt=$row['salt']."<br/><br/>";
echo "hashpassword ".$hashAndSalt=$row['hashpword'];
echo"<br/>";
}

$password="nony";



//$newhash = password_hash($password+$salt, PASSWORD_DEFAULT);


if (password_verify($password, $hashAndSalt)) {
   echo"verified";
}
else
{
echo"Not verified"; 
}
?>

回答by Rflujowa

You hash the password 2 times. Leave the crypt function and you should be ok.

您将密码散列 2 次。离开 crypt 功能,你应该没问题。

Just take a look at the PHP documentation regarding to password_verify and password_hash.

只需查看有关 password_verify 和 password_hash 的 PHP 文档即可。

Just save the password with password_hash(). that should store the hash in the DB.

只需使用 password_hash() 保存密码。应该将哈希存储在数据库中。

And to verify, you just compare the hash with the user input with password_verify. Password_verify will do the rest for you :)

为了验证,您只需将哈希值与用户输入的 password_verify 进行比较。Password_verify 将为您完成剩下的工作:)