Bcrypt在PHP中:如何快速且无错误地哈希密码

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Bcrypt在PHP中:如何正确且快速地哈希密码

\n\n

如果您曾经问过自己“如何在PHP中使用bcrypt进行密码哈希?”,那么您并不孤单。这个问题在Stack Overflow上获得了数千次浏览——这并非没有原因。密码哈希是任何Web应用程序安全的基础,而bcrypt仍然是最可靠和最流行的算法之一。在本文中,我们将探讨如何在PHP中使用bcrypt,如何配置它以获得最佳性能,并避免常见陷阱。

\n\n

为什么选择bcrypt?因为它通过内置的“盐值”和可调节的复杂度,能够抵御暴力破解攻击。但是,如何确保您的网站在每次登录时不会变慢呢?这正是我们要讨论的。

\n\n

什么是bcrypt,为什么它比MD5或SHA1更好?

\n\n

让我们直接澄清一点:永远不要使用MD5或SHA1来哈希密码。这些算法是为快速计算而设计的,而不是为了安全。相反,bcrypt是特意设计为慢速的。它使用成本因子,该因子决定了将执行多少次哈希迭代。成本因子越高,哈希计算的时间就越长——攻击者破解密码的难度也就越大。

\n\n

在PHP中,通过password_hash()和password_verify()函数,使用bcrypt变得非常简单。这些函数自PHP 5.5起引入,并已成为事实上的标准。

\n\n

如何在PHP中使用bcrypt:基本示例

\n\n

让我们从一个简单的例子开始。以下是注册用户并保存其密码的方法:

\n\n
<?php\n// 用户注册\n$password = "MySuperP@ss123";\n$hash = password_hash($password, PASSWORD_BCRYPT);\n\n// 将$hash保存到数据库(例如,在password_hash字段中)\necho $hash; // 输出类似 $2y$10$...\n?>
\n\n

以下是在登录时验证密码的方法:

\n\n
<?php\n// 用户登录\n$loginPassword = "MySuperP@ss123";\n$storedHash = "$2y$10$..."; // 来自数据库\n\nif (password_verify($loginPassword, $storedHash)) {\n    echo "密码正确!";\n} else {\n    echo "密码错误。";\n}\n?>
\n\n

很简单,对吧?但细节决定成败。让我们深入了解成本因子。

\n\n

配置成本因子:安全性与速度之间的平衡

\n\n

默认情况下,PASSWORD_BCRYPT使用成本因子 = 10。这意味着2^10 = 1024次迭代。在现代服务器上,这大约需要0.1–0.2秒。看起来不多,但如果您有1000个并发登录——时间就会开始增加。

\n\n

如何选择最佳成本因子?有一个简单的规则:它应该使得在您的服务器上哈希一个密码所需的时间不超过0.5秒。您可以通过使用不同值的password_hash()函数来测试这一点。

\n\n

以下是一个性能测试示例:

\n\n
<?php\n$password = "test_password";\n$times = [];\n\nfor ($cost = 8; $cost <= 14; $cost++) {\n    $start = microtime(true);\n    password_hash($password, PASSWORD_BCRYPT, ['cost' => $cost]);\n    $times[$cost] = microtime(true) - $start;\n}\n\nprint_r($times);\n?>
\n\n

在典型的共享主机上,成本因子10–12是最佳的。如果您有强大的服务器,可以提高到13–14。但不要过度:过高的成本因子可能导致您的服务器在遭受攻击时将所有资源都用于哈希计算。

\n\n

PHP中bcrypt的性能优化

\n\n

现在进入最有趣的部分——如何在不牺牲安全性的情况下让bcrypt更快。以下是一些经过验证的策略:

\n\n

1. 缓存结果

\n

如果用户输入了正确的密码,为什么每次请求都要重新哈希它?您可以使用Redis或Memcached将结果缓存一小段时间(例如5分钟)。这尤其

博客

书籍推荐