前端用 SHA-256 加密用户密码真的安全吗?

ლ倚凡 阅读 5

我最近在做一个登录页面,想在前端用 SHA-256 对用户密码做哈希后再传给后端,但听说这样其实不安全?

我试了用 Web Crypto API 做哈希,代码大概长这样:

async function hashPassword(password) {
  const encoder = new TextEncoder();
  const data = encoder.encode(password);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}

但同事说这根本防不住中间人攻击,而且等于把加密逻辑暴露给攻击者……到底该不该在前端做 SHA-256?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
ლ超霞
ლ超霞 Lv1
你同事说得对,前端单独用 SHA-256 确实没什么安全感。

我之前项目也踩过这个坑,当时觉得前端加密了传输就安全了,结果被安全审计的同学一顿锤。

问题在哪呢?中间人攻击的情况下,攻击者不需要知道原始密码是什么,他只需要拿到你传的那个 SHA-256 哈希值,就能直接重放攻击——因为后端验证的就是这个哈希值。这就好比你换了个锁,但钥匙就挂在门上一样。

还有两个致命问题:一个是 SHA-256 算得太快,暴力破解成本极低;另一个是没加盐的话,同样的密码哈希值全世界都一樣,彩虹表分分钟给你安排上。

那正确的姿势是什么?

首先,密码传输必须走 HTTPS,这个是底线。只要 HTTPS 保证了,密码在传输过程中就是加密的,攻击者截获不到明文。

然后,后端存储的时候必须加盐,并且用慢哈希算法。bcrypt、scrypt、argon2 这些都行,它们设计上就是算得慢,防止暴力破解。

如果你非要较劲,说“我们就要在前端做点加密”,也不是不行,但得用非对称加密——后端给你公钥,你用公钥加密密码再传过去。这样中间人只能拿到密文,无法重放。不过说实话,既然有 HTTPS 了,这个操作意义不大,纯属增加复杂度。

所以结论就是:前端别搞 SHA-256 哈希了,老老实实走 HTTPS,后端用 bcrypt 之类的加盐慢哈希存密码,这才是正路。
点赞
2026-03-18 17:01