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 密钥管理最佳实践》。