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

ლ倚凡 阅读 58

我最近在做一个登录页面,想在前端用 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?

我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
Code°保艳
在前端用 SHA-256 加密用户密码确实不安全,主要是因为几个关键问题。首先,中间人攻击是个大问题,即使你用了 HTTPS,把哈希逻辑放在前端等于直接暴露给任何能拦截请求的人。

再说性能上,就算 SHA-256 比较高效,但这种单次哈希很容易被暴力破解。专业点说,前端加密更像是给用户一种虚假的安全感。

比较好的做法是完全在后端做密码处理,用专门设计的算法比如 bcrypt、argon2 这种带盐和多轮迭代的方案。后端处理的好处是你能把加密逻辑藏起来,而且可以自由调整安全性参数。

如果非要前端做点什么,建议只用 HTTPS 保证传输安全,然后让后端接管所有密码处理工作。简单来说,前端负责收集密码,后端负责安全存储和验证,这才是最省心又安全的做法。

顺便说下你的代码实现虽然没问题,但用在这种场景就是浪费精力,不如专注优化其他更有价值的部分。
点赞
2026-03-31 06:14
ლ超霞
ლ超霞 Lv1
你同事说得对,前端单独用 SHA-256 确实没什么安全感。

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

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

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

那正确的姿势是什么?

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

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

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

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