MD5、SHA-1、SHA-256 怎么选:散列算法现状与使用边界
最后更新:2026-09-14
散列(哈希)函数把任意长度的输入映射成固定长度的输出,且满足两个性质:同样的输入永远得到同样的输出;从输出反推输入在计算上不可行。这两条性质决定了它的用途,也决定了它的边界。
选型的核心问题不是「哪个算法更强」,而是「这个用途需要抵抗什么攻击」。同一个算法在不同用途下的结论可能完全相反。
一、先分清散列与加密
- 散列是单向的,没有密钥,无法还原原文,用于完整性校验与指纹;
- 对称加密用同一个密钥加解密,可还原,但密钥管理是难点;
- 非对称加密用公钥加密、私钥解密(或反向签名),可还原或可验证来源;
- HMAC是「带密钥的散列」,既不可还原又能验证「谁生成的」,常用于接口签名。
二、各算法的安全现状
- MD5:碰撞已被实用化——可以构造两段不同内容却产生相同摘要。因此不能用于签名、证书、口令存储;用于非对抗场景(自检、缓存键、去重指纹)仍可,但要清楚它已不提供抗篡改能力;
- SHA-1:碰撞已被实际演示,主流浏览器与证书体系均已弃用。同样不应出现在任何安全相关的新设计中;
- SHA-256 / SHA-512:目前没有实用碰撞攻击,是通用场景的默认选择;
- SHA-3 / BLAKE2 / BLAKE3:结构上与 SHA-2 系列不同,具备多样性价值;BLAKE 系列在同等安全强度下速度更快,适合大文件校验;
- CRC32:不是密码学散列,只用于检测随机传输错误,可被轻易构造出碰撞,切勿用于安全校验。
三、按用途选型
- 文件完整性 / 下载校验:SHA-256 或 BLAKE3。只要校验值本身来自可信渠道(同站公布、签名文件),即可有效发现篡改;
- 缓存键 / 数据去重 / 分片:MD5 或更快的非密码学散列足够,性能优先;
- 接口签名 / 防篡改:HMAC-SHA256,密钥不参与传输;
- 数字签名与证书:SHA-256 及以上配合非对称密钥;
- 口令存储:MD5、SHA-1、SHA-256 都不合格,必须用慢哈希,见下一节。
四、为什么口令不能用普通散列
普通散列被设计成「计算很快」,这对口令存储是致命缺点:攻击者可以每秒尝试数十亿次猜测,配合预先计算好的大量常见口令摘要表,能在很短时间内还原出弱口令。
口令存储需要的是「慢」:bcrypt、scrypt、Argon2 这类算法通过可调的计算成本与内存占用,把单次校验压到毫秒级,使暴力枚举变得不可承受。它们的输出中还包含算法参数与随机盐,因此同一口令在不同用户处会得到不同摘要,从根本上破坏预计算表的作用。
五、加盐与彩虹表
盐是每个用户独立的一段随机值,与口令拼接后再散列。它的两个作用:让相同口令产生不同摘要(防止一次破解影响多个账户),以及让预先算好的摘要对照表失效。
关键点是盐必须随机且与摘要一起保存,不需要保密。把盐写成全局固定值、或用用户名当盐,都只是部分有效——攻击者可以为每个用户名单独预计算。
六、使用中的常见错误
- 在客户端做一次散列再发给服务端,并把它当成「加密传输」——摘要本身就成了口令,抓到即可重放;
- 把 MD5 用于「防篡改」判断,却忽略了攻击者可以同时替换内容与摘要;
- 比较摘要时使用普通字符串相等判断,理论上存在时序侧信道,安全场景应使用常量时间比较;
- 把散列值当作唯一标识并在多处展示,导致内部数据结构随算法变更而全部失效。
七、工具与延伸
需要即时计算摘要或比对两段内容时,可用 在线哈希计算工具,支持 MD5、SHA-1、SHA-256、SHA-512。关于「能贴进在线工具吗」的判断方法,见《在线工具安全吗》;接口密钥的生成与轮换见《API 密钥管理最佳实践》。