如何使用 PHP 的password_hash来散列和验证密码

2022-08-30 07:04:50

最近,我一直在尝试在互联网上偶然发现的登录脚本上实现自己的安全性。在努力学习如何制作自己的脚本为每个用户生成盐之后,我偶然发现了。password_hash

根据我的理解(基于此页面上的阅读),当您使用时,行中已经生成了盐。这是真的吗?password_hash

我的另一个问题是,有2种盐不是很聪明吗?一个直接在文件中,一个在数据库中?这样,如果有人在数据库中破坏了您的盐,您仍然直接在文件中拥有一个盐?我在这里读到,储存盐从来都不是一个聪明的想法,但它总是让我感到困惑,人们的意思是什么。


答案 1

使用是存储密码的推荐方法。不要将它们与数据库和文件分开。password_hash

假设我们有以下输入:

$password = $_POST['password'];

您首先通过执行以下操作来散列密码:

$hashed_password = password_hash($password, PASSWORD_DEFAULT);

然后查看输出:

var_dump($hashed_password);

如您所见,它是散列的。(我假设你做了这些步骤)。

现在,您将此哈希密码存储在数据库中,确保密码列足够大以容纳哈希值(至少 60 个字符或更长时间)。当用户要求登录时,您可以在数据库中使用此哈希值检查密码输入,方法是执行以下操作:

// Query the database for username and password
// ...

if(password_verify($password, $hashed_password)) {
    // If the password inputs matched the hashed password in the database
    // Do something, you know... log them in.
} 

// Else, Redirect them back to the login page.

官方参考


答案 2

是的,您理解正确,函数password_hash()将自行生成盐,并将其包含在生成的哈希值中。将盐存储在数据库中是绝对正确的,即使已知,它也能完成其工作。

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);

// 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($_POST['password'], $existingHashFromDb);

您提到的第二种盐(存储在文件中的盐)实际上是胡椒或服务器端密钥。如果你在散列之前添加它(如盐),那么你就加了一个胡椒。不过,有一种更好的方法,您可以首先计算哈希值,然后使用服务器端密钥加密(双向)哈希值。这使您可以在必要时更改密钥。

与盐相反,这个钥匙应该保密。人们经常把它混为一谈,试图隐藏盐,但最好让盐做它的工作,并用钥匙添加秘密。


推荐