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

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

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

开始课程

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

\n\n

您是否曾想过,为什么您的PHP网站在用户注册时会卡顿?或者更糟的是,为什么黑客仍然能够从您的数据库中窃取密码?答案可能在于您如何使用bcrypt在PHP中哈希密码。

\n\n

这个问题是Stack Overflow上最热门的问题之一(数千次浏览!)。这并不奇怪:密码安全是一个领域,一个错误就可能让您失去声誉,而用户则可能失去他们的数据。但今天,我们不仅仅要讨论如何使用password_hash配合bcrypt。我们将讨论优化和性能。因为,您得承认,登录时等待5秒钟并不酷。

\n\n

让我们弄清楚如何让PHP中的密码哈希既安全又快速。开始吧!

\n\n

为什么选择bcrypt?为什么不用MD5或SHA?

\n\n

许多新手(唉,还有一些“老手”)仍然在使用md5()或sha1()。这就像用塑料门闩锁门——看似锁上了,但只需吹口气就能打开。MD5和SHA是快速哈希。太快了。使用现代GPU的黑客每秒可以破解数十亿个这样的哈希。

\n\n

Bcrypt是一种完全不同的方法。它被特意设计为慢速的。它使用“盐”(随机数据)和“cost factor”(成本因子),迫使算法执行更长时间。当黑客计算一个bcrypt哈希时,他们本可以破解一百万个MD5哈希。这就是为什么bcrypt是PHP的事实标准。

\n\n

基础:如何在PHP中正确使用bcrypt

\n\n

从PHP 5.5开始,我们有了神奇的password_hash()函数。忘掉手动添加盐和调用crypt()吧——一切都已经为您做好了。

\n\n

以下是使用bcrypt正确哈希密码的样子:

\n\n
<?php\n// 哈希密码\n$password = 'MySuperSecretPassword123!';\n$hash = password_hash($password, PASSWORD_BCRYPT);\n\necho $hash;\n// 输出:$2y$10$...(长度为60个字符的字符串)\n?>
\n\n

就这样!password_hash会自动生成随机盐并选择最佳的cost factor(默认为10)。那么登录时如何验证密码呢?

\n\n
<?php\n// 验证密码\n$inputPassword = 'MySuperSecretPassword123!';\n$hashFromDB = '$2y$10$...'; // 来自数据库的那个哈希\n\nif (password_verify($inputPassword, $hashFromDB)) {\n    echo "密码正确!欢迎您。";\n} else {\n    echo "密码错误。请重试。";\n}\n?>
\n\n

很简单,对吧?但魔鬼总是藏在细节中。让我们谈谈最重要的事情——性能。

\n\n

优化bcrypt:如何在安全性和速度之间找到平衡

\n\n

影响PHP中bcrypt性能的主要参数是cost factor(成本因子)。它在password_hash()中作为第二个参数以数组['cost' => 12]的形式设置。

\n\n

什么是cost?这是一个对数尺度。每增加一个单位,执行时间大约翻倍。

\n\n
    \n
  • Cost = 10(默认值):约0.1-0.2秒。很快,但对于2024年来说已经有点低了。
  • \n
  • Cost = 12:约0.4-0.8秒。对于大多数项目来说是一个很好的平衡。
  • \n
  • Cost = 14:约1.5-3秒。非常安全,但用户可能会开始不耐烦。
  • \n
  • Cost = 16+:>5秒。除非您是间谍或存储核代码,否则不要用。
  • \n
\n\n

如何选择理想的cost?有一个简单的规则:在您的服务器上,哈希一个密码的时间不应超过250-500毫秒。这对用户来说是无感的,但会使黑客的暴力破解攻击成本过高。

\n\n

测试性能

博客

书籍推荐