【问题标题】:How to verify password against database?如何根据数据库验证密码?
【发布时间】:2023-03-22 09:56:01
【问题描述】:

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

Using PHP 5.5's password_hash and password_verify function

然而,我不确定我是否以正确的方式散列和加盐!

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

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

$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"; 
}

它与“未验证”相呼应

【问题讨论】:

  • @user3633383,什么值?嗯,我得到了盐字符串和散列密码,但是当我验证时它说未验证
  • 好吧,我以前没用过这些功能。似乎正在发生的事情是您正在对密码进行哈希处理,然后使用它来验证它是否是有效密码。 password_verify() 采用未散列的原始密码。

标签: php hash


【解决方案1】:

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

因此没有理由自己执行相同的步骤(不要调用 crypt() 并且不要生成盐)。不建议生成自己的 salt,因为您无法比 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);

【讨论】:

    【解决方案2】:

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

    //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"; 
    }
    

    所以前提是你已经将哈希值存储在数据库中

    $newhash=$row['hashpword'];//taken from db
    $password="pwtester";//user keyed in password
    
    if (password_verify($password, $newhash)) {
        echo"verified";
    }
    else
    {
        echo"Not verified"; 
    }
    

    应该可以!

    【讨论】:

    • 请看一下我编辑的代码:我不确定如何验证我的盐然后散列..为了额外的安全性,我需要手动加盐
    【解决方案3】:

    密码存储:

    $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"; 
    }
    ?>
    

    【讨论】:

      【解决方案4】:

      您对密码进行了 2 次哈希处理。 离开 crypt 功能应该没问题。

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-03
        • 2012-11-05
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 2016-01-16
        相关资源
        最近更新 更多