口令为什么要用慢哈希
口令存储的正确做法是「慢哈希 + 每用户独立盐 + 可调成本」:bcrypt、scrypt、Argon2 专为抗暴力破解设计,靠可调的计算或内存成本把单次尝试的成本抬高;而 MD5、SHA-1、SHA-256 这类通用摘要速度快,用 GPU 每秒可以试上亿次组合,一旦数据库泄露等于口令全泄。
基本信息
| 通用推荐 | bcrypt,成本因子可调,注意 72 字节输入上限 |
|---|---|
| 内存硬算法 | scrypt,靠内存消耗抵抗 GPU 与 ASIC |
| 新系统首选 | Argon2id,密码竞赛优胜,兼顾抗侧信道与抗 GPU |
| 合规场景 | PBKDF2,FIPS 环境常用,需加大迭代次数 |
| 盐的规则 | 每用户独立随机盐,长度 16 字节以上,与哈希一起存储 |
| 参数校准 | 以登录耗时为准(例如控制在 250 毫秒以内) |
典型使用场景
- 新系统做用户口令存储选型:直接选 Argon2id 或 bcrypt
- 老系统巡检:发现 SHA-256 单轮直存或加固定盐,评估迁移方案
- 登录接口存在暴力破解风险时,配合失败锁定与限速一起加固
- 做平滑迁移:用户下次登录时用新算法重新计算并覆盖旧哈希
- 评估成本参数:在不同硬件上实测登录耗时,避免过低或过高
- 合规审计:确认算法、参数与盐的生成方式满足规范要求
最小示例
最小示例
# 生成一个 Argon2id 哈希(示意参数,具体以所用库文档为准)
# memory=64MB, iterations=3, parallelism=1, salt 16 字节随机
# 校验时把存储的盐与参数一起读出来重新计算并做常量时间比较
# 迁移流程
# 1) 老哈希格式保留可识别前缀,登录成功且前缀为旧算法时重新计算
# 2) 重新计算成功后写回新格式,失败不影响本次登录
# 3) 长期未登录的账号到期强制重置口令算法速查
| 算法 | 特点 | 推荐度 |
|---|---|---|
| bcrypt | 成熟稳定,成本因子可调,输入截断 72 字节 | 通用推荐 |
| scrypt | 内存硬,抗 GPU 与 ASIC,参数需调优 | 推荐 |
| Argon2id | 密码竞赛优胜,综合最优 | 新系统首选 |
| PBKDF2 | 老标准,FIPS 合规环境常见 | 合规环境 |
| MD5 / SHA 系列 | 速度快,可被 GPU 每秒尝试上亿次 | 仅作校验用途,不可存口令 |
发现历史遗留的弱哈希不要直接删表重建:走「登录时重算」的平滑迁移路径,用户体验无损,也不需要强行重置全员口令。
不要把哈希成本参数调得过高:故意拖慢登录的副作用是登录接口更容易被压垮,高并发场景建议把成本参数与限速策略一起评估。