如何针对数据库验证密码?

she*_*rly 5 php hash

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

使用PHP 5.5的password_hash和password_verify函数

但是,我不确定是否要按照正确的方式进行哈希处理和加盐处理或过度使用!

我想使用自己的盐,然后再进行哈希处理。盐密码和哈希密码都存储在数据库中的两个不同字段中。

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

$cost = 10;
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
$salt = sprintf("$2a$%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);
Run Code Online (Sandbox Code Playgroud)

鉴于此,我试图按以下方式验证密码:某种程度上,我觉得我在使过程复杂化。

$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"; 
}
Run Code Online (Sandbox Code Playgroud)

编辑:

现在,我这样存储:

$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);
Run Code Online (Sandbox Code Playgroud)

但是验证令人困惑:

$email = "test55@gmail.com";
$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"; 
}
Run Code Online (Sandbox Code Playgroud)

回显“未验证”

mar*_*kli 7

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

因此,您没有理由自己执行相同的步骤(不要调用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);
Run Code Online (Sandbox Code Playgroud)


Zas*_*ast 5

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

//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"; 
}
Run Code Online (Sandbox Code Playgroud)

因此,前提是您已将哈希存储在数据库中

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

if (password_verify($password, $newhash)) {
    echo"verified";
}
else
{
    echo"Not verified"; 
}
Run Code Online (Sandbox Code Playgroud)

应该管用!