Bcrypt哈希生成与验证
在线生成和验证Bcrypt密码哈希,支持自定义cost轮次,所有计算在浏览器本地完成
4(最快,约 1ms)
12(最慢,约 1s)
关于 Bcrypt
- Bcrypt 是专为密码存储设计的自适应哈希函数,内置盐值(Salt),相同密码每次生成不同哈希
- cost 参数控制计算轮次(2^cost 次),值越大越安全但越慢,生产环境建议 ≥ 10
- 广泛用于用户密码存储,是 Spring Security、Laravel、bcrypt.js 等框架的默认密码哈希方案
操作说明
- 生成模式:输入明文密码,调整 cost 轮次,点击「生成哈希」
- 验证模式:输入明文密码和已有哈希值,点击「验证」判断是否匹配
- 点击「示例」自动填入演示数据;支持 Ctrl+Enter 快捷键触发操作
- 点击输入框右侧眼睛图标可切换密码显示/隐藏
注意事项
- Bcrypt 是单向哈希,无法解密,只能通过验证模式比对明文与哈希
- cost 越高越安全,但 cost=12 在浏览器中约需 1 秒,请根据场景选择
- 所有计算均在浏览器本地完成,密码不会上传至服务器
- 生成的哈希以
$2a$开头,包含算法版本、cost 和盐值信息
Bcrypt 知识详解
Bcrypt 哈希结构解析
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
| 片段 | 示例值 | 说明 |
|---|---|---|
$2a$ | $2a$ | 算法版本(2a/2b/2y) |
| cost | 10 | 计算轮次(2^10 = 1024 次迭代) |
| 盐值(22字符) | N9qo8uLOickgx2ZMRZoMye | 随机生成,Base64编码,防彩虹表攻击 |
| 哈希值(31字符) | IjZAgcfl7p92ldGxad68LJZdL17lhWy | 实际哈希结果,Base64编码 |
Cost 参数与性能对照
| Cost | 迭代次数 | 典型耗时 | 适用场景 |
|---|---|---|---|
| 4 | 16 | ~1ms | 测试环境 |
| 8 | 256 | ~10ms | 低性能设备 |
| 10 | 1,024 | ~100ms | 生产环境(推荐) |
| 12 | 4,096 | ~400ms | 高安全场景 |
随着硬件性能提升,建议每隔几年将 cost 值增加 1
Bcrypt vs 其他密码哈希方案
| 算法 | 自适应 | 内置盐值 | 推荐程度 | 说明 |
|---|---|---|---|---|
| MD5/SHA1 | ❌ | ❌ | ⛔ 不推荐 | 速度太快,易被暴力破解 |
| SHA256+盐 | ❌ | 需手动 | ⚠️ 勉强 | 无自适应,硬件加速后不安全 |
| Bcrypt | ✅ | ✅ | ✅ 推荐 | 经过时间验证,广泛支持 |
| Argon2 | ✅ | ✅ | ✅ 最推荐 | PHC 冠军,抗 GPU 攻击更强 |
| scrypt | ✅ | ✅ | ✅ 推荐 | 内存密集型,抗 ASIC 攻击 |
各语言使用示例
Node.js(bcryptjs)
const bcrypt = require('bcryptjs');
const hash = await bcrypt.hash('password', 10);
const ok = await bcrypt.compare('password', hash);
const hash = await bcrypt.hash('password', 10);
const ok = await bcrypt.compare('password', hash);
Java(Spring Security)
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
String hash = encoder.encode("password");
boolean ok = encoder.matches("password", hash);
String hash = encoder.encode("password");
boolean ok = encoder.matches("password", hash);
C#(BCrypt.Net)
string hash = BCrypt.Net.BCrypt.HashPassword("password", 10);
bool ok = BCrypt.Net.BCrypt.Verify("password", hash);
bool ok = BCrypt.Net.BCrypt.Verify("password", hash);