密码该用哪个哈希:MD5、SHA-256 与 bcrypt 的分工

密码学 · 2 分钟阅读· 247 次阅读

「MD5 不安全」这句话半对:它在抗碰撞上确实破了,但用在非安全场景(缓存键、去重)依然合适。

真正危险的是用 MD5/SHA-256 存密码——它们太快,快就是弱点。

先说结论

密码用 argon2id 或 bcrypt,完整性用 SHA-256,身份认证用 HMAC。

  • 密码存储必须慢哈希 + 每用户盐
  • SHA-256 适合校验,不适合存密码
  • HMAC 用于消息认证,不要用 hash(key+msg)
  • 不要自己设计算法

漏洞是怎么产生的

哈希函数的速度决定了暴力破解的成本。SHA-256 每秒能算上亿次,bcrypt 只能算几千次——后者才是密码该用的。

加盐解决的是「彩虹表」与「相同密码相同哈希」,不解决「弱密码」。

修复与验证

修复不是改一行代码,而是四件事一起做:

  • 盘点现有存储:是否有 MD5/SHA1 存密码
  • 迁移到 bcrypt(cost 10-12)或 argon2id
  • 登录成功时透明升级旧哈希
  • 校验场景用 SHA-256,不用于密码
  • 消息认证用 HMAC-SHA256,不用拼接哈希

攻击面与检测点

按影响面排序,先修影响最大的:

场景 算法 原因
密码存储 argon2id/bcrypt 慢,抗暴力
文件校验 SHA-256 快且抗碰撞
消息认证 HMAC-SHA256 带密钥
缓存键 MD5/xxhash 速度优先

密码该用哪个哈希

几个容易踩的坑

下面这些是最常见的错误做法:

  • 用 MD5 存密码:GPU 秒破
  • 全局固定盐:等于没加盐
  • 自己实现加密逻辑:几乎一定有漏洞
  • 把哈希当加密:不可逆不代表安全

写在最后

选算法的第一步是明确「防谁、防多久」,而不是「哪个更新」。

安全不是一次加固,是持续的假设:假设输入不可信、假设边界会破、假设有人会看错。

评论 (3)

半
半箱油

修复清单比漏洞描述有用多了,很多文章只讲怎么打不讲怎么防。

白
白帽小林

白名单那条永远是最有效的,正则黑名单迟早绕过。

运
运维老张

建议再补一条:把这类检查加到 CI 里,靠人记必然漏。

发表评论

验证码

提交后需站长审核,通过后才会显示。