“用 MD5 还是 SHA-256?“——取决于你要防谁。哈希有两个完全不同的用途:完整性校验和对抗攻击。前者 MD5 够用,后者必须 SHA-256 起步。
5 个常见算法的定位
| 算法 | 输出长度 | 速度(相对) | 状态 |
|---|---|---|---|
| MD5 | 128 位 / 32 hex | 最快 | 2004 年起被证明可碰撞,不再用于安全场景 |
| SHA-1 | 160 位 / 40 hex | 快 | 2017 年 Google 实际制造碰撞,已废弃 |
| SHA-256 | 256 位 / 64 hex | 中等 | 当前主流安全哈希 |
| SHA-512 | 512 位 / 128 hex | 64 位机器上快于 SHA-256 | 对抗未来量子计算更从容 |
| BLAKE3 | 可变 | 比 MD5 还快 | 新一代,并行友好 |
什么叫”碰撞”
两个不同的输入得到相同的哈希值,叫碰撞。对于完美哈希,找一个碰撞需要尝试 2^(n/2) 次(生日悖论):
- MD5:2⁶⁴ ≈ 1800 亿亿次,本该极难,但算法设计有缺陷,实际可在 GPU 上几秒做出碰撞
- SHA-1:2⁸⁰ 次,Google 用 9223 万亿次 SHA-1 运算制造出两个不同 PDF 但哈希相同
- SHA-256:2¹²⁸ 次,目前全人类算力 100 万年也不够
用途和选型
完整性校验(非安全场景) 比如下载 Ubuntu ISO 后验证文件没损坏,MD5 就够了——你要防的是比特翻转,不是恶意构造。
密码存储
绝对不要用 MD5/SHA-256 直接哈希密码——GPU 每秒能算几百亿次。必须用 bcrypt/scrypt/argon2,它们故意慢(几十到几百毫秒一次),让暴力破解变得不可行。
HMAC 签名、证书、区块链 SHA-256 起步。需要抗量子攻击可考虑 SHA-512 或 SHA-3。
文件去重、缓存 key BLAKE3 是最佳选择,比 MD5 还快且无碰撞漏洞。如果不想引入新依赖,SHA-1 也够用(这是安全场景之外,碰撞风险可接受)。
一个常见误区:加盐 MD5
“MD5 加盐就安全了”——半对半错。加盐能防止彩虹表(预计算哈希字典),但挡不住 GPU 暴力。黑客拿到数据库后,对每条记录单独跑 GPU,每秒依然能测几十亿个候选密码。加盐 + bcrypt 才是完整方案,只加盐不换算法意义有限。
文件校验:大文件别全读两次
工具层面,好的实现应该用流式读取(边读边喂给哈希算法),而不是先把整个文件读进内存再算。一个 4GB ISO 文件应该在 5-10 秒内出 SHA-256,内存占用几 MB。
实际算一下
贴入文本或选择文件,MD5 / SHA-1 / SHA-256 / SHA-512 同时算出。做 HMAC 签名时多填一个 key,做文件校验时直接对比 hash 字符串就行。