前端能直接对用户密码做哈希吗?这样安全吗?
我最近在用 Vue 写一个登录页面,看到后端同事说密码要哈希存储,我就想能不能在前端先哈希再传给后端,省得传明文。但又听说这样其实不安全,有点懵。
我试了下用 crypto-js 在提交前处理密码,代码大概是这样:
<template>
<input v-model="password" type="password" />
<button @click="login">登录</button>
</template>
<script>
import CryptoJS from 'crypto-js'
export default {
data() { return { password: '' } },
methods: {
login() {
const hashed = CryptoJS.SHA256(this.password).toString()
// 发送 hashed 给后端
}
}
}
</script>
但这样真的安全吗?会不会反而有风险?
你现在的做法在前端做SHA256哈希,比传明文确实好一点,但有几个坑要注意:
1. 这样只是把密码变成了固定长度的哈希值,本质上还是相当于在传"密码",黑客拿到这个哈希值可以直接用来登录(这叫pass the hash攻击)
2. 如果没上HTTPS,中间人攻击照样能拿到你的哈希值
更安全的做法一般是:
前端传明文密码(必须用HTTPS),后端加盐再做哈希存储。因为后端可以做到:
- 每个用户用不同的盐值
- 使用专门设计的慢哈希算法(如bcrypt、PBKDF2)
- 可以灵活调整哈希强度
如果实在想在前端处理,至少应该:
1. 和后端约定好加盐方式(比如固定盐值+用户名)
2. 一定要配合HTTPS使用
3. 明确这只是二次防护,后端还是要做正规哈希
代码可以改成这样:
不过说实话,大厂现在基本都是直接传明文+HTTPS,把安全问题交给后端处理。前端搞哈希容易画蛇添足,除非有特殊需求。