密码不能原样保存到数据库里。那该怎么保存呢?答案就是哈希。本文讲解其机制,以及保证安全的要点(不会写出攻击步骤)。
哈希 ≠ 加密
两者常被混淆,但目的恰好相反。加密是「为了以后读回,可用密钥还原」的变换。**哈希是「无法还原(单向)」**的变换。密码这种信息,连运营方本来都不需要读回,所以特意采用无法还原的哈希更合适。
加密(可逆)
明文 ⇄ 密文。有密钥就能还原。适用于以后要读回的数据
哈希(单向)
密码 → 哈希值。无法还原。适用于保存密码
登录时,要看的是「把输入的密码用同样的步骤做哈希,再和已保存的哈希是否一致」。无需取出原始密码。
为什么「裸用 MD5/SHA-256」还不够
MD5 和 SHA-256 是快速哈希。这本是有用的特性,但在密码保存上却成了弱点。因为攻击者可以针对泄露的哈希,每秒计算海量候选来逐一比对。
- 彩虹表:把「常见密码→其哈希」预先计算好的巨大对照表。如果是裸哈希,只要查表就能找到匹配。
- 暴力破解(brute force):哈希越快,单位时间内能尝试的候选越多=越容易被攻破。
通用哈希与密码哈希的区别
两者都叫「哈希」,但设计用途不同。只有右侧那一列才适合用于保存密码。
| 通用哈希(MD5、SHA-1、SHA-256) | 密码哈希(Argon2id、bcrypt、scrypt、PBKDF2) | |
|---|---|---|
| 设计用途 | 检测文件篡改、签名等 | 保存密码 |
| 速度 | 越快越好 | 故意做得很慢(可调) |
| salt | 不在设计之内 | 在设计之内(PBKDF2 由调用方提供) |
| 调节成本 | 不可以 | 成本、迭代次数或内存;随时间提高 |
| 用于保存密码 | 不要用 | 使用 |
NIST SP 800-63B-4 同样要求,用以 salt 和成本因子为输入的密码哈希方案来保存密码,成本要在不影响性能的前提下尽量设高,并随时间提高。
两项安全措施
加上 salt(每个用户不同的值)
保存前,先为每个用户混入一个不同的随机值(salt),再做哈希。这样即使密码相同,每个人的保存值也各不相同,彩虹表被废掉,对重复使用密码的批量破解也无从下手。
使用故意做得很慢的专用哈希
bcrypt / Argon2 / scrypt 可以把计算有意做得很重(成本参数)。对正常登录的单次而言慢到无所谓,但能把攻击者的暴力破解拖到现实中不可行的速度。salt 的添加也已内置其中。
真实案例:泄露通知里写着「已哈希」时
泄露公告有时会说明密码是以明文、哈希还是加密的形式保存的。下面把本站报道过的案例按保存方式整理。
| 案例 | 公布的密码相关信息 | 对用户意味着什么 |
|---|---|---|
| 宅ふぁいる便(Takufile-bin)(2019 年) | 以明文保存 | 可以原样读出。使用相同密码的其他服务也有风险 |
| 樱花互联网(Sakura Internet)(2026 年) | 部分初始密码没有做哈希 | 仍在使用初始密码的人需要立即修改 |
| Gyazo(2026 年) | 密码哈希泄露;未公布方式 | 视方式而定可能被还原。该公司要求用户修改密码 |
阅读通知时要记住两点:
- 仅凭「已哈希」无法判断是否安全。裸 MD5 和加了 salt 的慢速哈希,在密码被还原的难易程度上差别巨大
- 如果没有写明方式,就按方式薄弱来应对。修改该服务以及其他使用相同密码的服务的密码
可以通过如何检查密码是否已泄露,确认你的邮箱地址是否出现在过去的泄露中。
如何检查自己的网站和账户
作为用户:留意密码重置的方式
如果「忘记密码」会把原来的密码通过邮件发给你,这个服务很可能以明文或可还原的形式保存密码。不要在那里使用你在其他地方也用的密码。
作为开发者:检查用哪个函数保存密码
找出代码中用来保存和验证密码的函数。PHP 的 password_hash()、Django 内置的认证、或 bcrypt/Argon2 库都是密码专用的,能满足基本要求。凡是直接调用 md5()、sha1() 或 sha256 的地方,都是迁移对象。
作为开发者:检查保存的值和设置
如何识别已保存的哈希、OWASP 的最低设置、以及如何从薄弱算法迁移,见密码的安全保存方法。
本站观点:不要自己拼凑
以为「给 MD5 加个 salt 就够了」,是一个常见的错误。安全的密码保存,要把 salt 的生成与保管、计算成本的调节、对时序差异的考量都包含进来,才算成立。比起自己东拼西凑,交给语言、框架的官方密码函数(很多内部都用 bcrypt/Argon2)来处理,在本站看来才是最安全、最可靠的。新项目请把 Argon2id 作为首选。
出处(一手资料)
- NIST,“SP 800-63B-4 Digital Identity Guidelines: Authentication and Authenticator Management”(2025 年 8 月) — pages.nist.gov(以 salt 和成本因子为输入的哈希方案、随时间提高成本)
- OWASP,“Password Storage Cheat Sheet” — cheatsheetseries.owasp.org(哈希与加密的区别、推荐算法、工作因子)
- RFC 9106,“Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications” — rfc-editor.org
- 各案例的出处(各公司自己的公告)列在本站链接的文章中
继续阅读
- 术语:salt 是什么(让重复使用密码的攻击失效的、每个用户不同的随机值)
- 对策:密码的安全保存方法(哈希+salt 实践)
- 入门:密码的正确保管(别再明文保存) / 如何选择密码管理器
- 案例:宅ふぁいる便(Takufile-bin)信息泄露事件(2019)(明文保存密码的真实案例)