跳到正文
>_ITDITDWeb 安全平台

术语表

密码哈希是什么 — 用不可逆的单向变换安全保存密码的机制

密码哈希是一种用不可逆的单向变换来保存密码的方法。本文隐去攻击步骤、从防御视角讲解它与加密(可解密)的区别、直接使用 MD5 或 SHA-256 为何危险(彩虹表·暴力破解),以及正确做法 salt+慢速哈希(bcrypt/Argon2/scrypt)。

发布于 2026-06-27 更新于 2026-06-27 1 分钟阅读

「密码不能『原样』保存到数据库里」——那该怎么保存呢?答案就是哈希。本文讲解其机制,以及保证安全的要点(不会写出攻击步骤)。

哈希 ≠ 加密

两者常被混淆,但目的恰好相反。**加密是「为了以后读回,可用密钥还原」**的变换。哈希是「无法还原(单向)」的变换。密码这种信息,连运营方本来都不需要读回,所以特意采用无法还原的哈希更合适。

加密(可逆)

明文 密文。有密钥就能还原。适用于以后要读回的数据

哈希(单向)

密码 哈希值。无法还原。适用于保存密码

密码用『无法还原』的哈希来保存。与加密(可还原)的目的恰好相反。

登录时,要看的是「把输入的密码用同样的步骤做哈希,再和已保存的哈希是否一致」。无需取出原始密码。

为什么「裸用 MD5/SHA-256」还不够

MD5SHA-256快速哈希。这本是有用的特性,但在密码保存上却成了弱点。因为攻击者可以针对泄露的哈希,每秒计算海量候选来逐一比对。

  • 彩虹表:把「常见密码→其哈希」预先计算好的巨大对照表。如果是裸哈希,只要查表就能找到匹配。
  • 暴力破解(brute force):哈希越快,单位时间内能尝试的候选越多=越容易被攻破。

让它安全的两个机制

1

加上 salt(每个用户不同的值)

保存前,先为每个用户混入一个不同的随机值(salt),再做哈希。这样即使密码相同,每个人的保存值也各不相同,彩虹表被废掉,对重复使用密码的批量破解也无从下手。

2

使用故意做得很慢的专用哈希

bcrypt / Argon2 / scrypt 可以把计算有意做得很重(成本参数)。对正常登录的单次而言慢到无所谓,但能把攻击者的暴力破解拖到现实中不可行的速度。salt 的添加也已内置其中。

本站观点:不要自己拼凑

「给 MD5 加个 salt 不就够了吗?」——这正是典型的陷阱。安全的密码保存,要把 salt 的生成与保管、计算成本的调节、对时序差异的考量都包含进来,才算成立。比起自己东拼西凑,交给语言、框架的官方密码函数(很多内部都用 bcrypt/Argon2)来处理,在本站看来才是最安全、最可靠的。新项目请把 Argon2id 作为首选。

继续阅读

FAQ

Q哈希和加密有什么区别?
A

加密是『有密钥就能还原(可解密)』的变换,用于以后需要读回数据的场景。哈希是『无法还原(单向)』的变换。密码本来就不需要运营方读回,所以特意采用无法还原的哈希更合适。即便数据库被盗,也无法从哈希中直接取出原始密码。

Q用 MD5 或 SHA-256 做哈希就安全吗?
A

仅此还不够。MD5/SHA-256 是『快速』哈希,攻击者每秒能尝试海量候选,因此常见密码会被暴力破解或彩虹表(预先计算好的对照表)攻破。要做到安全,需要为每个用户加上不同的『salt』,并使用『故意做得很慢』的专用哈希(bcrypt·Argon2·scrypt)。

Q到底该用哪一个?
A

新项目首选 Argon2(尤其是 Argon2id),其次是 bcrypt 或 scrypt。它们的机制中都内置了 salt 的添加与计算成本的调节。比起自己拼凑 MD5+salt,使用这些标准实现(语言/框架的官方函数)更安全、更可靠。