最近,我一直在尝试用我在互联网上偶然发现的脚本在一个日志上实现我自己的安全性。 在努力学习如何编写自己的脚本为每个用户生成一个salt之后,我偶然发现了password_hash
。
根据我的理解(基于本页的阅读),当您使用password_hash
时,已经在行中生成了salt。 这是真的吗?
我的另一个问题是,有两种盐不是很聪明吗? 一个直接在文件中,一个在数据库中? 这样,如果有人破坏了DB中的salt,您仍然直接在文件中保留salt? 我在这里读到储存盐从来都不是一个聪明的主意,但它总是让我搞不懂人们的意思。
建议使用password_hash
存储密码。 不要将它们分离到DB和文件中。
假设我们有以下输入:
$password = $_POST['password'];
我并不只是为了理解概念而验证输入。
首先通过以下步骤对密码进行散列:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
然后查看输出:
var_dump($hashed_password);
正如你所看到的,它是散列的。 (我想你已经做了这些步骤)。
现在,您将此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.
官方参考
是的,您正确理解了它,函数password_hash()将自己生成一个salt,并将其包含在结果的哈希值中。 将salt存储在数据库中是绝对正确的,即使已知,它也能完成它的任务。
// 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);
您提到的第二个salt(存储在文件中的salt)实际上是一个pepper或服务器端密钥。 如果你在碎之前加入它(就像盐),那么你就会加入胡椒粉。 但是有一个更好的方法,您可以首先计算散列,然后用服务器端密钥加密(双向)散列。 这使您有可能在必要时更改密钥。
与盐相反,这把钥匙应该保密。 人们常常把它混在一起,试图把盐藏起来,但最好还是让盐各司其职,用一把钥匙把秘密加进去。
是的,是真的。 为什么你怀疑php关于函数的faq? :)
运行password_hash()
的结果有四个部分:
因此,正如您所看到的,散列是它的一部分。
当然,您可以使用额外的salt来增加安全性层,但我真诚地认为在常规php应用程序中这是过度的。 默认的bcrypt算法很好,可选的blowfish算法甚至更好。