PHP 中的密码哈希

Olorunfemi Akinlua 2023年1月30日
  1. PHP 中的密码哈希
  2. 在 PHP 中使用 password_hash()password_verify() 进行密码散列
PHP 中的密码哈希

PHP 用于服务器端开发,在构建登录和注册过程时需要密码。出于安全目的和隐私问题,我们需要对我们的密码进行哈希处理,这样任何人(包括你和你的数据库管理员)都无法知道用户的密码。

但是,当我们对密码进行哈希处理时,当我们想登录时,我们需要对其进行重新哈希处理。本文详细介绍了密码哈希处理以及如何使用 PHP 内置函数 password_hash()password_verify() .

PHP 中的密码哈希

从用户那里收集的数据存储在数据库中,任何有权访问数据库的人都可以看到这些数据。用户名和地址通常保持原样;它们不如你帐户的密钥重要。

作为用户密码的文本字符串通过散列算法(bcrypt、md5、sha-1、sha-2)传递,以防止按原样保存密码并创建文本的加扰表示。密码的这个加扰表示被存储,并且在登录过程中,加扰表示被比较。

内置的 password_hash() 函数使用 bcrypt 算法,这是 Auth0 推荐的 并用于其客户群。此外,password_verify() 函数将密码文本与哈希值进行比较,并在密码与哈希值匹配时返回布尔值。

在 PHP 中使用 password_hash()password_verify() 进行密码散列

当用户访问你的站点并创建一个新帐户时,作为 PHP 开发人员,你将确保你的应用程序对密码进行哈希处理。为此,我们应用 password_hash() 函数。

<?php

$password = "24FE21121@1*?"; // password the user imputs.
echo password_hash($password, PASSWORD_DEFAULT); // outputs the hashed password

?>

代码片段的输出是:

$2y$10$YRmyqWGiHbDSI31XbD2DuOzmTKSjYSSgR.2.3rYCmSSFS/xlAtb3.

代码片段使用默认散列算法,根据 PHP 文档,该算法使用 bcrypt 算法。如果我们打算改变散列算法,我们可以改变函数的第二个参数。

我们可以使用其他三个可能的参数(散列算法)。PASSWORD_BCRYPTPASSWORD_ARGON2IPASSWORD_ARGON2ID 是支持的参数。

PASSWORD_BCRYPT 使用 CRYPT_BLOWFISH 算法,PASSWORD_ARGON2I 使用 Argon2i 散列算法,而 PASSWORD_ARGON2ID 使用 Argon2id 散列算法。要更好地了解每种算法的工作原理,请查看 PHP 密码哈希文档

让我们在我们的代码中尝试 PASSWORD_BCRYPT 参数。

<?php

$password = "24FE21121@1*?"; // password the user imputs.
echo password_hash($password, PASSWORD_DEFAULT); // outputs the hashed password

?>

代码片段的输出是:

$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO

PASSWORD_DEFAULTPASSWORD_BCRYPT 都使用 $2y$ 标识符,并将生成 60 个字符的字符串。通过上述过程,我们成功地对用户的密码进行了哈希处理。

现在,如果用户想登录他的帐户,我们需要将他们输入的密码与散列密码进行比较。这就是 password_verify() 发挥作用的地方。

我们可以将密码和存储的哈希密码与内置函数进行比较。

<?php

$password = "24FE21121@1*?";
$hashed_password ='$2y$10$YRmyqWGiHbDSI31XbD2DuOzmTKSjYSSgR.2.3rYCmSSFS/xlAtb3.';

print_r(password_verify($password, $hashed_password));

?>

代码片段的输出是:

1

在 PHP 中,1 代表,0 代表

让我们对由 PASSWORD_BCRYPT 参数生成的散列密码尝试 password_verify() 函数。

<?php

$password = "24FE21121@1*?";
$hashed_password = '$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO';

print_r(password_verify($password, $hashed_password));

?>

代码片段的输出是:

1

无论我们使用什么散列密码,password_verify() 函数都可以工作的原因是因为该函数验证与 crypt() 兼容的给定散列匹配,两者兼而有之。此外,这些函数将算法、成本和盐作为返回哈希的一部分返回,并且可以安全地抵御计时攻击

要改善你的哈希结果,请在 password_hash() 函数中指定成本和盐选项。但是,如果你不了解如何使用它,它会极大地影响你的安全

要检查 password_verify() 函数是否会捕获错误密码,让我们输入一个错误密码(从 24FE21121@1*? 更改为 24Fqqw1121@1*?)。

<?php

$password = "24Fqqw1121@1*?";
$hashed_password = '$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO';

if (password_verify($password, $hashed_password)) {
    echo "Password Matches!";
} else {
    echo "Wrong Password";
}

?>

代码片段的输出是:

Wrong Password

如果我们在实际登录过程的上下文中使用它,代码可能如下所示:

<?php
$connect = mysqli_connect($localhost, $username, $password, $database);

if (isset($_POST['submit'])) {
    extract($_POST);

    // retrive stored hashed password
    $sqlQuery = mysqli_query($connect, "SELECT * FROM USERTABLE WHERE USER='$username'");
    $fetch = mysqli_fetch_array($sqlQuery);
    $currentPassword = $fetch['hashPassword'];

    if (password_verify($enteredPassword, $currentPassword)) {
        // password matches
        $_SESSION['id'] = $fetch['id'];
        header("location: home.php");
    } else {
        // password doesn't match
        $output = "Wrong Passworfd";
    }
}
Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn

相关文章 - PHP Password