哈希与摘要算法速查
MD5 和 SHA-256 差在哪、为什么 MD5 不能再用于安全场景、CRC32 和加密哈希有什么本质区别、密码该用哪种算法存。
哈希函数把任意长度的输入变成固定长度的输出,并且满足三个特性:同样的输入永远得到同样的输出;输入改一点点,输出会面目全非;从输出无法反推输入。这三条决定了它的用途。
但不同哈希算法的「强度」差别很大:有的已经被证明可以构造出碰撞(两份不同内容得到相同哈希),有的专门设计成算得很慢以抵抗暴力破解。分清楚「校验用」和「存密码用」,才不会用错。
1常见算法对照
输出长度是最直观的区别,但真正的差别在抗碰撞能力与设计目标。
| 算法 | 输出长度 | 安全状态 | 典型用途 |
|---|---|---|---|
MD5 | 128 位(32 位十六进制) | 已被攻破,可构造碰撞 | 历史遗留的校验与标识,不应再用于安全场景 |
SHA-1 | 160 位(40 位十六进制) | 已被攻破,碰撞已有实例 | 旧系统中的版本号与提交标识仍可见,新系统不用 |
SHA-256 | 256 位(64 位十六进制) | 目前安全 | 文件校验、数字签名、区块链,当前主流选择 |
SHA-512 | 512 位(128 位十六进制) | 目前安全 | 同上,在 64 位平台上速度有优势 |
SHA-3 / Keccak | 可配置(224 至 512 位) | 目前安全 | SHA-2 的备选标准,结构不同,用于前瞻性设计 |
CRC32 | 32 位 | 非加密算法 | 传输与存储的差错检测,不防篡改 |
bcrypt / scrypt / Argon2 | 可配置 | 专为密码设计 | 密码存储,故意设计得很慢且可加盐 |
「哈希长度」指的是输出位数,不是输入限制。哈希函数可以接受任意长度的输入,输出长度却固定——这正是它能把一个几 GB 的文件压缩成一行摘要的原因。
2哈希、加密、编码的根本区别
这三个词经常被混用,但它们解决的是完全不同的问题,混用会导致安全设计出错。
| 特性 | 哈希(摘要) | 加密 | 编码 |
|---|---|---|---|
| 可否还原 | 不可还原(单向) | 可还原(有密钥) | 可还原(无需密钥) |
| 是否需要密钥 | 不需要 | 需要密钥 | 不需要 |
| 输入与输出长度 | 输出定长 | 输出通常与输入等长或略长 | 输出随输入增长 |
| 目的 | 校验完整性、存密码、生成指纹 | 保密传输与存储 | 适配传输或存储环境 |
| 典型例子 | SHA-256、MD5、bcrypt | AES、RSA、ChaCha20 | Base64、URL 编码、UTF-8 |
| 能否用于保密 | 不能(内容不可还原但会暴露指纹) | 能 | 不能(任何人都能解) |
「把密码用 Base64 编码存起来」是最经典的错误——Base64 是编码不是加密,任何人都能立刻解出原文。同理,把 MD5 当作「加密后的密码」也不对:MD5 是单向摘要,会被彩虹表撞库。这两类误解在实践中造成过大量泄露事故。
3为什么 MD5 和 SHA-1 不能再用于安全场景
它们并非「算得不准」,而是「可以被故意构造出碰撞」——攻击者能做出两份内容不同、但哈希值相同的文件。
- 碰撞的含义
- 两份不同的输入得到相同的哈希值。哈希的抗碰撞性被破坏意味着「哈希相同」不再能证明「内容相同」
- MD5 的现状
- 碰撞构造已非常廉价,普通算力即可在短时间内算出。它作为文件指纹已不可靠
- SHA-1 的现状
- 碰撞已被实际构造出来(著名的 SHAttered 实验),主流浏览器与证书机构已停止使用
- 实际风险
- 攻击者可准备两份内容不同的文件,让它们哈希相同。用哈希做完整性校验时,替换文件后校验仍然「通过」
- 仍有价值的场合
- 在不涉及对抗的场景(如缓存键、数据分片、非对抗性去重)中,MD5 的速度优势仍可用,但必须清楚它不提供安全保证
- 迁移建议
- 把校验与签名改用 SHA-256 及以上;把密码存储改用 bcrypt、scrypt 或 Argon2
4密码存储为什么要用慢哈希
存密码不能用普通哈希的直觉是:快速算法对攻击者同样有利。密码场景的对手是「拿到数据库后离线暴力破解」,所以要让破解尽可能慢。
| 做法 | 原理 | 评价 |
|---|---|---|
| 直接存明文 | 不处理 | 最严重的事故,一旦泄露全部账号失守 |
| 存 MD5 等快速哈希 | 单次哈希 | 不安全:现代显卡每秒可计算数十亿次,弱密码瞬间被穷举 |
| 加盐 + 快速哈希 | 每个密码加随机盐再哈希 | 挡住了彩虹表,但仍挡不住高速穷举,仍不推荐 |
bcrypt | 可调工作因子的慢哈希 | 推荐,工作因子越高越慢,可按硬件发展调整 |
scrypt | 同时消耗计算与内存 | 推荐,内存消耗让它更难被专用硬件加速 |
Argon2 | 密码哈希竞赛的获胜方案 | 当前首选,可分别调节时间、内存与并行度 |
| 加盐的作用 | 每个用户用不同的随机盐 | 相同密码得到不同哈希,杜绝一次撞库全中 |
「慢」是密码哈希的特性而非缺陷。一个登录请求多花 100 毫秒对用户几乎无感,但攻击者尝试十亿次密码的时间会从几小时变成几十年。所以密码哈希应该用专门设计为慢的算法,而不是把 SHA-256 反复执行几千次(虽然原理类似,但专门的算法在设计上更严谨)。
5实际使用中的四个坑
- 用哈希校验下载文件
- 哈希只能证明「文件与发布者提供的哈希一致」,前提是这个哈希本身通过可信渠道获得。从同一个被入侵的页面拿到文件和哈希,等于没校验
- 比较哈希值时用普通字符串比较
- 安全场景下应使用恒定时间比较,避免通过响应时间差异推断出部分正确内容(时序攻击)
- CRC32 当作防篡改手段
- CRC32 是为检测意外传输错误设计的,攻击者可以轻易构造出 CRC 相同的内容。它防不了恶意篡改
- 统一用同一个盐
- 盐必须每个用户不同且随机。所有用户共用一个盐,效果接近不加盐,且会增加「批量破解」风险
看完就能用的站内工具
全部工具总览 →关于「哈希与摘要算法速查」的常见问题
MD5 和 SHA-256 有什么区别?
主要差别在输出长度、抗碰撞能力与安全状态。MD5 输出 128 位(32 位十六进制字符),SHA-256 输出 256 位(64 位十六进制字符),更长的输出意味着找到碰撞的难度呈指数级上升。更关键的是,MD5 已被证明可以廉价地构造碰撞,也就是能做出两份内容不同但哈希相同的文件,因此它作为安全指纹已经不可靠;SHA-256 目前仍被认为是安全的。速度上 MD5 更快,所以在完全不涉及对抗的场景(如缓存键、非安全性的数据去重)仍可能见到它,但凡是涉及完整性校验、签名、密码的场合都应使用 SHA-256 及以上。
哈希和加密有什么区别?
最本质的区别是「能不能还原」。哈希是单向的,从摘要无法反推出原文,所以它适合证明「内容没变过」或「密码输入正确」,但因为不可还原,它不能用于需要把内容取出来的场合。加密是双向的,用密钥可以把密文还原成明文,因此用于保密传输与存储。另外编码(如 Base64)也常被误认为加密,它既不需要密钥也不保密,任何人都能解码,只是把内容换成另一种字符表示而已。实际使用中要按需求选择:要保密用加密,要校验用哈希,要适配传输格式用编码。
文件校验该用哪个哈希算法?
推荐 SHA-256。它在当前仍被认为安全,输出长度为 64 个十六进制字符,便于核对,而且几乎所有平台都有现成实现。SHA-512 在 64 位平台上速度更好,同样可用。应避免用 MD5 与 SHA-1,因为它们已被证明可以构造碰撞,也就是说攻击者有可能伪造出一份内容不同但哈希相同的文件来骗过校验。不过要强调一点:哈希校验的前提是「哈希值本身通过可信渠道获取」。如果攻击者能同时替换文件和页面上公布的哈希,校验就失去了意义,这种情况下需要依赖数字签名。
密码应该怎么存才安全?
核心原则是使用专门为密码设计的慢哈希算法,而不是 MD5、SHA-256 这类快速哈希。推荐的选择是 bcrypt、scrypt 或 Argon2:它们都可以设置工作因子,让单次计算故意变慢,而且都有加盐机制,为每个用户生成不同的随机盐,使得相同密码得到不同哈希,避免一次撞库全部命中。bcrypt 出现早、生态成熟,是大量系统的默认选择;scrypt 和 Argon2 额外消耗内存,对专用破解硬件的抵抗更强,Argon2 是当前密码哈希竞赛的推荐方案。绝对不要存明文,也不要用「Base64 编码后存储」这种看似处理过实则等价于明文的方式。
继续查:相关内容
全部速查 →内容说明:本页速查数据由本站自行整理,事实性内容以对应官方规范与文档为准,未复制第三方速查表或百科的表述。数据最后核对日期:2026-10-05。若发现错误或已更新的标准,欢迎通过页脚反馈入口告知。
速查在线工具箱