加密与安全系列 · 第 6 章
密码应该怎么存:加盐、慢哈希与 bcrypt 的三道防线
WebTool 团队 · 发布于 2026-09-08 · 密码 / bcrypt / 安全 / 后端
密码存储的正确答案:bcrypt / scrypt / argon2 这类「慢哈希 + 自动加盐」算法,任何快速的通用哈希(MD5/SHA 家族)都不合格——哪怕加了盐。 本站提供随机密码生成工具生成高强度密码。
三道防线的演进
防线一:不存明文。 库被拖了(脱库)是概率事件而非假设事件,明文存储意味着所有用户密码直接泄露,且用户常在多站复用密码,危害会放大。
防线二:加哈希。 哈希不可逆,但通用哈希太快了——一张消费级显卡每秒可算数百亿次 MD5,常见密码字典加暴力枚举很快就能跑完。
防线三:慢哈希 + 盐。
- 盐(salt):每个密码配一段随机值一起哈希,让相同密码的哈希结果不同,彩虹表和批量破解失效。盐不需要保密,和哈希一起存即可。
- 慢(工作因子):bcrypt 的 cost 参数让单次计算耗时可控地变长(如 100ms)。用户登录感知不到,攻击者的穷举成本却放大亿倍。算力变强后调大 cost 即可续命。
对比表
| 方案 | 抗彩虹表 | 抗 GPU 穷举 | 结论 |
|---|---|---|---|
| 明文 | ❌ | ❌ | 禁止 |
| MD5(password) | ❌ | ❌ | 禁止 |
| SHA-256(salt+password) | ✅ | ❌(太快) | 不合格 |
| bcrypt / argon2 | ✅ | ✅ | 标准答案 |
完整链路提醒
- 传输靠 HTTPS,不要在客户端先哈希再传——那会让哈希值本身变成「等价密码」。
- 存储字段留足长度:bcrypt 结果固定 60 字符,但 argon2 的 PHC 字符串更长,数据库列建议 VARCHAR(255)。
- 登录失败提示不要区分「用户不存在」和「密码错误」,否则可被用于枚举有效账号。
- 加图形/行为验证码与限流,挡住在线撞库。
最后更新:2026-09-08