PHP散列密码,每个 PHP 程序员在某个时候都需要编写一个依赖于用户登录才能正常运行的应用程序。用户名和密码通常存储在数据库中,然后用于身份验证。众所周知,密码永远不应以明文形式存储在数据库中:如果数据库遭到破坏,所有密码都将被公开供恶意行为者使用。这就是为什么我们需要了解如何散列密码。

PHP散列密码
请注意我们是如何使用散列一词而不是加密的?这是因为散列和加密是非常不同的过程,经常被混淆。
哈希
散列函数采用类似字符串mypassword123
并将其转换为字符串的加密版本,称为散列。例如,mypassword123
可能会被散列以生成看似随机的数字和字母字符串,例如9c87baa223f464954940f859bcf2e233
. 散列是一种单向函数。一旦你散列了一些东西,你就会得到一个固定长度的字符串——一个不能轻易逆转的过程。
我们可以比较两个哈希来检查它们是否都来自同一个原始字符串。在本文的后面,我们将了解如何使用 PHP 实现此过程。
加密
与哈希类似,加密会将输入字符串转换为看似随机的数字和字母字符串。但是,加密是一个可逆过程——如果您知道加密密钥。因为它是一个可逆过程,所以它不是密码的好选择,但对于点对点安全消息传递之类的事情来说是极好的选择。
如果我们加密密码而不是对其进行哈希处理,并且我们正在使用的数据库以某种方式被恶意第三方访问,则所有用户帐户都将受到威胁——这显然不是一个好场景。
盐
密码在散列之前也应该加盐。加盐是在对密码进行哈希处理之前将随机字符串添加到密码中的操作。
通过加盐密码,我们可以防止字典攻击(攻击者系统地输入字典中的每个单词作为密码)和彩虹表攻击(攻击者使用常用密码的哈希列表)。
在加盐之上,我们应该在散列时使用某种程度上安全的算法。这意味着它应该是一种尚未被破解的算法,最好是一种专用算法而不是通用算法(如 SHA512)。
截至 2023 年,推荐的哈希算法为:
- Argon2
- Scrypt
- bcrypt
- PBKDF2
使用 PHP 进行哈希处理
自 PHP5.5 引入函数以来,PHP 上的散列变得很容易password_hash()
。
目前,它使用 bcrypt(默认情况下)并支持其他哈希算法,如 Argon2。该password_hash()
功能还负责为我们加盐密码。
最后,它返回哈希密码。成本和盐作为散列的一部分返回。
简单来说,密码哈希的成本是指生成哈希所需的计算量。这就像衡量创建散列的“难度”。成本越高,难度越大。
想象一下,你想做一个蛋糕,蛋糕的食谱上写着“鸡蛋打五分钟”。这就是制作蛋糕的“成本”。如果你想让蛋糕更“安全”,你可以把食谱改成“鸡蛋打十分钟”。现在做蛋糕的时间变长了,等于增加了做蛋糕的“成本”。
password_hash()
正如我们在文档中看到的那样:
…验证散列所需的所有信息都包含在其中。这允许 [
password_verify()
] 函数无需单独存储 salt 或算法信息即可验证散列。
这确保我们不必在我们的数据库中存储额外的信息来验证哈希返回。
在实践中,它看起来像这样:
<?php $password = "sitepoint"; $hashed_password = password_hash($password, PASSWORD_DEFAULT); if (password_verify($password, $hashed_password)) { //if the password entered matches the hashed password, we're in } else { // redirect to the homepage }
有关该功能的更多信息可在此处password_hash()
找到,同时可在此处找到。password_verify()
PHP散列密码结论
对于 PHP 程序员来说,了解散列和加密之间的区别,并使用散列来存储密码以保护用户帐户免受损害是很重要的。在 PHP 5.5 中引入该password_hash()
函数使程序员可以轻松地使用各种算法(包括 Argon2 和 bcrypt)安全地散列密码。
PHP 包含一种非常安全的散列密码方法。它是由比你我更了解这些东西的人创建的,它避免了像我们这样的开发人员需要完全了解可能发生的安全问题。出于这个原因,强烈建议我们使用内置的 PHP 算法来散列密码,而不是创建我们自己的。
确保您考虑到这一点并及时了解最新推荐的哈希算法,以确保您的应用程序尽可能安全。
推荐阅读