Bcrypt 哈希与验证

在浏览器中为密码生成加盐 bcrypt 哈希,并用明文验证已有哈希。

在浏览器中为密码生成加盐 bcrypt 哈希,并用明文验证已有哈希。 在浏览器中为密码生成加盐 bcrypt 哈希,并用明文验证已有哈希。

生成的 bcrypt 哈希

背景知识

什么是 bcrypt,为什么它很重要

bcrypt 是 1999 年由 Niels Provos 和 David Mazieres 设计的自适应密码哈希函数。 与 MD5、SHA-256 这类快速摘要不同,bcrypt 有意消耗 CPU 时间:每次哈希都会以可 配置的轮数运行 Blowfish 加密算法,成本因子每增加 1,工作量就翻一倍。这种减速 正是让离线字典攻击和暴力破解变得昂贵的原因。正确的 bcrypt 实现还会把 128 位 随机盐嵌入输出字符串,因此同一密码的两次哈希结果总是不同,彩虹表对它也毫无 用处。

如何读懂 bcrypt 哈希

一个 bcrypt 哈希形如 $2b$12$e0.6kJ8a5X8u5Yp3qR5E0e9dF4z3W2c1v0b9n8m7l6k5j4h3g2f1。 开头的美元符号分隔的各段携带算法版本、成本和盐:

  • $2b$ -- 算法修订版本。$2a$$2y$ 是较老的变体,对 8 位符号位缺陷的 处理略有不同;$2b$ 是当前推荐版本,也是 bcryptjs 的输出格式。
  • 12 -- 成本因子。2^12 = 4096 轮密钥扩展。每 +1 时间翻倍;交互式登录默认 10-12 即可,存储凭据可用 12-14。
  • 其余 53 个字符包含 22 字符(128 位)base64 盐和 31 字符(184 位)校验和。 整个字符串是一条自包含记录:验证器从哈希中读回版本、成本和盐,重新执行 派生流程进行比对。

如何使用本工具

在输入框中输入密码,选择成本因子,然后点击"生成哈希"。生成的哈希会出现在 输出框中,并同时填入验证字段。要检查已有哈希,把哈希粘贴到验证字段,然后在 输入框中输入候选密码:页面会立即比对,显示绿色对勾或红色叉号。由于比对使用 bcrypt.compareSync 完成,它永远不会暴露错误猜测的接近程度——每次尝试都会完整 哈希后才得出结果。

安全说明与局限

bcrypt 会把输入截断到 72 字节:更长的密码会被静默截断,因此前 72 字节相同的 两个密码会被判定相等。如果需要更长输入,先用 SHA-256(十六进制)预哈希,再对 摘要做 bcrypt。bcrypt 是刻意轻内存的算法——它对 GPU 阵列的抵抗不如 Argon2 或 scrypt 这类内存硬算法,但 4KB 表和 64 字节状态仍然让廉价的 ASIC 破解缺乏吸引 力。全新系统通常更适合 Argon2id;bcrypt 依然是兼容性极好、广受支持的选项, 尤其适合无法提供 Argon2 的运行环境。本页面完全在浏览器中运行:密码和哈希 永远不会离开你的设备,代码路径(MIT/BSD 的 bcryptjs)已内置于 public/assets。

使用 BSD-3-Clause 协议的 bcryptjs 库(已内置于 public/assets)。哈希在本地完成,不传输任何数据。

常见问题

为什么同一个密码每次生成的哈希都不一样?
每次哈希都会生成一个 128 位随机盐并嵌入输出中。验证时会从哈希中重新读取盐,因此正确性不受影响,但相同输入永远不会产生相同输出。
我应该使用多大的成本因子?
交互式登录建议 10-12;存储凭据可以用 12-14。成本越高越安全但越慢,请选择服务器每次登录可承受的最大值。
2026 年 bcrypt 仍然推荐吗?
是的。bcrypt 依然广泛部署,成本 ≥10 时被认为是安全的。全新系统通常更倾向内存硬算法 Argon2id 或 scrypt,但 bcrypt 仍是经过实战检验的优秀选择,尤其在无法使用这些算法时。
为什么 bcrypt 比 SHA-256 慢?
这正是它的设计目的。SHA-256 追求速度,攻击者每秒可尝试数十亿次猜测;bcrypt 昂贵的密钥扩展和盐迫使攻击者为每次猜测付出真实时间,使离线攻击变得不切实际。
72 字节限制对我的密码意味着什么?
bcrypt 会忽略第 72 字节之后的内容。超过 72 字节且前缀相同的两个密码会被验证为相同。要支持更长的秘密,先用 SHA-256(十六进制)哈希再对摘要做 bcrypt。
我的密码会被发送到服务器吗?
不会。所有操作都在浏览器本地使用内置的 bcryptjs 库完成。页面加载后即使断网也能正常工作。