• 你还在纠结前端要不要提交明文口令?
  • 发布于 2个月前
  • 295 热度
    6 评论
你还在纠结前端要不要提交明文口令?这个十年前就有结论的问题每隔一段时间都会有人讨论。结论是不管什么环境,前端提交 hash 后的口令总是好的,防的不是中途的嗅探者,而是脱库后的破解者。前端 hash 越耗时,脱库后跑字典越慢。至于前端 hash 也不用自己捣鼓 js/wasm 这些,主流浏览器早已内置 PBKDF2 算法,较新的 CPU 都有相应的硬件加速,比自己实现可以快很多倍。

演示:
const username = new TextEncoder().encode('alice')
const password = new TextEncoder().encode('hello1234')

// 重复 1000 万次 SHA256
const pbkdfOpts = {
  name: 'PBKDF2',
  hash: 'SHA-256',
  salt: username,
  iterations: 1e7,
}

async function pbkdf2(pwd, opts, bits) {
  const baseKey = await crypto.subtle.importKey('raw', pwd, 'PBKDF2', false, ['deriveBits'])
  const buf = await crypto.subtle.deriveBits(opts, baseKey, bits)
  return new Uint8Array(buf)
}

const dk = await pbkdf2(password, pbkdfOpts, 256)

// 注册/登录提交 dk 即可,无需提交 password
console.log(dk)


用户评论
  • 暮涵
  • 后端存密码加的盐越多,密码就越安全,不过事实上没什么用。现在基本靠二次验证做保护,账户内消费靠二级密码。
  • 2024/5/27 16:56:00 [ 0 ] [ 0 ] 回复
  • 紫烟追梦
  • 我简单科普一下,可能有些新人不了解 PBKDF2一个 hash 函数,比如 sha256 为了防止被破解,需要加入密码,起名为 HMAC 。而 PBKDF2 ,就是针对于 HMAC 递归计算,次数就是 OP 里的 1000 万次,计算量的增加,大大加强了 HMAC 的安全性。

    而网页登陆的用户名,就是 hash 函数的密码(也叫 salt)这样做有什么好处呢,那就是针对用户名 A 建立的彩虹表,无法用于用户名 B/C/D 。不同用户名只能单独计算,这就增加了密码防撞的安全性。
  • 2024/5/27 16:46:00 [ 0 ] [ 0 ] 回复
  • 激情飞扬
  • 这算法自古以来就有,早在 linux 还叫 unix 年代,password 就为了防止本地账号密码破解,启用了递归 hash 算法,那时候是 md5 递归 1000 次,代码里还专门注明了一句:just to make sure things don't run too fast 。
  • 2024/5/27 16:39:00 [ 0 ] [ 0 ] 回复
  • Jeanks
  • 前端能 hash ,后端也能 hash,大多数情况下脱库都是查彩虹表,这种场景下一个靠谱的 hash 才是关键,而不是在哪一端 hash 的。
  • 2024/5/27 16:34:00 [ 0 ] [ 0 ] 回复
  • 青墨断笺
  • 我觉得还是不 hash 更好,用非对称加密传输。10 年前前端 hash 用的是 md5 ,现在认为 md5 不安全,你只能把 md5 当原始密码再做一次新 hash ,要是未来新 hash 算法也被认为不安全,你是不是要再套一层?
    前端传可解密的密文,更能适应技术升级,未来你 db 用的 hash 算法被认为不安全了,也可以在用户重新登录时更换新的 hash 算法。而前端传 hash ,未来前端技术升级,你要把 hash 当密码,要么同时传可解密密码和 hash ,反正原 hash 是甩不掉了。
  • 2024/5/27 16:29:00 [ 0 ] [ 0 ] 回复
  • 白笙枫客
  • 后端用慢 hash 来增加密文泄漏时候的暴力破解成本,但是用户量大了的话后端自己很难扛住这么大量的慢 hash 计算量,所以把计算过程分到前端去做,本质上不是为了安全(虽然后端上慢 hash 确实是为了安全),而是一种分布式计算的方案。
  • 2024/5/27 16:15:00 [ 0 ] [ 0 ] 回复