配置
生成用于存储密码的 bcrypt 哈希,并验证密码是否与现有哈希匹配。在生成模式下选择成本和版本;在验证模式下粘贴哈希和要检查的密码。结果会显示哈希的各个部分以及计算所用的时间。

bcrypt 哈希无法“解密”:要确认密码是否正确,请使用验证模式。所有计算都在你的浏览器中完成,密码不会发送到任何服务器。

参数
4 到 15 之间

当前版本。由 OpenBSD、Node.js、Python、Go 和 Rust 生成。

成本每增加 1,计算时间就翻倍。OWASP 建议至少为 10;理想值是服务器能在约 250 毫秒内算完的最高值。

0 / 72 字节

工作原理

bcrypt 是专为存储密码设计的哈希函数。与几微秒就能算完的 SHA-256 或 MD5 不同,bcrypt 故意设计得很慢:这样即使有人窃取了数据库,用暴力破解尝试密码也要花上数年。

每个哈希都包含验证所需的全部信息:算法版本、成本和 128 位随机盐值。因此同一密码每次都会得到不同的哈希,也无需单独存储盐值。

成本是轮数以 2 为底的对数:成本 10 计算 1024 轮,成本 12 计算 4096 轮。每增加 1,计算时间翻倍,从而无需更换算法就能跟上硬件性能的提升。

示例

rasmuslerdorf$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1aPHP 手册中 password_verify() 的示例:在验证模式下将它与该密码一起粘贴,即可看到匹配。
abc$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0ijBCrypt 中成本为 6 的测试向量。成本之后的前 22 个字符是盐值,其余 31 个字符是哈希结果。

使用场景

  • 为管理员用户的初始密码生成哈希,直接插入数据库。
  • 用户无法登录时,检查密码是否与存储的哈希匹配。
  • 为 Laravel、Spring、Django 或 Node.js 应用的 fixtures、seeds 或自动化测试生成测试哈希。
  • 在服务器上配置之前,测量每种成本的耗时,选择合适的值。
  • 为 Apache 的 .htpasswd 文件创建条目,它接受前缀为 $2y$ 的 bcrypt 哈希。

常见问题

bcrypt 哈希可以解密吗?

不能。bcrypt 是单向函数:无法从哈希中还原密码。唯一能做的是尝试候选密码,看是否有匹配的,而 bcrypt 正是要让这个过程变慢。

$2a$、$2b$ 和 $2y$ 有什么区别?

对普通密码而言,三者计算结果相同。$2a$ 是原始版本;$2y$ 是 PHP 在 2011 年引入的,用来把自己的哈希与一个存在缺陷的实现区分开;$2b$ 是 OpenBSD 在 2014 年修复另一个与超过 255 个字符的密码有关的缺陷时采用的。几乎所有库在验证时都接受这三种版本。

应该使用多大的成本?

OWASP 建议至少为 10。理想值是服务器每次登录能在约 250 毫秒内算完的最高值。Spring Security 默认使用 10;Laravel 11 和 PHP 8.4 已将默认值提高到 12。

为什么 bcrypt 会忽略超过 72 字节的部分?

该算法把密码用作 Blowfish 的密钥,而密钥最多 72 字节。超出部分会被静默丢弃,因此前 72 字节相同的两个密码会得到相同的哈希。带重音的字符或表情符号占 2 到 4 个字节,所以本工具统计的是字节数而不是字符数。

bcrypt 和 Argon2 哪个更好?

目前新系统推荐使用 Argon2id,因为它不仅慢,还占用大量内存,提高了 GPU 攻击的成本。不过只要成本设置合适,bcrypt 依然安全,而且它是 PHP、Laravel、Spring 和 Ruby on Rails 的默认算法。

我的密码会发送到服务器吗?

不会。哈希的生成和验证都在你的浏览器中完成,密码永远不会离开你的设备;分享工具的链接中也不会包含密码。