我阅读了许多与这个主题相关的文章,例如:
使用PHP 5.5's 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);
鉴于此,我试着验证密码,如下所示:不知何故,我觉得我使这个过程复杂化了。
$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";
}
编辑:
现在我像这样存储:
$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);
但验证混乱:
$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";
}
显示"Not Verified"
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);
这将正确验证,正如它应该的那样。
//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";
}
如果您已经将哈希值存储在db
中$newhash=$row['hashpword'];//taken from db
$password="pwtester";//user keyed in password
if (password_verify($password, $newhash)) {
echo"verified";
}
else
{
echo"Not verified";
}
应该工作!
密码存储:
$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);
密码验证:
<?php
include('config.php');
$email = "test55@gmail.com";
$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";
}
?>
密码散列了2次。离开crypt函数,你应该没问题。
看一下关于password_verify和password_hash的PHP文档。
使用password_hash()保存密码。将哈希值存储在DB中。
要验证,只需将哈希值与用户输入的password_verify进行比较。Password_verify将为您完成其余的工作:)