别再纠结前端要不要提交明文口令,浏览器已经内置非常好的方案

30 天前
 iqoo

这个十年前就有结论的问题每隔一段时间都会有人讨论。结论是不管什么环境,前端提交 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)

9400 次点击
所在节点    程序员
93 条回复
lisxour
30 天前
你强任你强,md5 一把梭
passon
30 天前
@lisxour md5 公司已经不让用在密码场景了
LandCruiser
30 天前
前端明文提,后端就要铭文存?什么逻辑啊。。。
majula
30 天前
可以了解一下 PAKE ,比传统的 KDF 泄露密码的风险更低。

我们公司网站目前用的是 OPAQUE: https://www.ietf.org/archive/id/draft-irtf-cfrg-opaque-02.html
iqoo
30 天前
@LandCruiser KDF 计算量太大,后端算成本太高。
beginor
30 天前
iqoo
30 天前
@beginor 支持的,演示代码可以跑。不过 FireFox 没有加速,比 chrome 慢一倍。
tool2dx
30 天前
iterations: 1e7, 那么大的递归数值?绝了,确实普通 PC 没办法轻易破解。

就是怕老 arm 手机浏览器,会算不过来。
HojiOShi
30 天前
@beginor #6 我用 Firefox 125 跑上面的 demo 没问题啊,生成结果也和 Chrome 一致。
StevenRCE0
30 天前
谢谢科普,马了
Chad0000
30 天前
不管你怎么算的,都可以将算的结果认为是“密码”,服务端认这个“密码”就得。

当天强度不够了,要升级:服务端没办法认新的算法了吧?必须得强迫用户重置密码?
kdwnil
30 天前
道理我都懂,但是

> Crypto.subtle
> 安全上下文: 此项功能仅在一些支持的浏览器的安全上下文( HTTPS )中可用。

而更有必要倒腾前端加密的 http 页面被完全排除在外,另外一般脱库得到的是加密后的 hash ,也没法拿去撞库吧
Puteulanus
30 天前
后端用慢 hash 来增加密文泄漏时候的暴力破解成本,但是用户量大了的话后端自己很难扛住这么大量的慢 hash 计算量,所以把计算过程分到前端去做,本质上不是为了安全(虽然后端上慢 hash 确实是为了安全),而是一种分布式计算的方案
GaGaGood
30 天前
@Chad0000 同疑问
iqoo
30 天前
@Chad0000 其实是重置“强度”,口令本身不用改。后端要求升级时,用户登录时把旧的 KDF 和新的 KDF 都提交上去,旧的用于验证,新的用于更新。
Chad0000
30 天前
@iqoo #15
假如有 N 个版本呢?还得记录每次用户的密码?或者 N 个版本所有终端不能同时升级到最新版,那么有的旧版的终端怎么办?
lovelylain
30 天前
我觉得还是不 hash 更好,用非对称加密传输。
10 年前前端 hash 用的是 md5 ,现在认为 md5 不安全,你只能把 md5 当原始密码再做一次新 hash ,要是未来新 hash 算法也被认为不安全,你是不是要再套一层?
前端传可解密的密文,更能适应技术升级,未来你 db 用的 hash 算法被认为不安全了,也可以在用户重新登录时更换新的 hash 算法。而前端传 hash ,未来前端技术升级,你要把 hash 当密码,要么同时传可解密密码和 hash ,反正原 hash 是甩不掉了。
chingyat
30 天前
@Chad0000 不太会有多个版本吧,hash 算法更新换代没那么快
Chad0000
30 天前
@chingyat #18
就算没有多个版本,你现在需要升级算法。但:你有网页版和 APP 版,前者容易,后者你都不一定能限定用户必须使用某个版本的 APP 。你直接停掉之前所有版本的 APP 强迫用户升级?还是你做兼容(意味着保存多个密码版本)?
iminto
30 天前
看得我一头雾水,我是不是穿越了?

16 年前,人人网最红火的年代,就看过有人研究人人网的爬虫,它的登录就是用的 RSA 算法做加密的。现在都 2024 了,还有人讨论这类的问题吗?

至于有一层楼 @majula 提到的 PAKE 算法,怎么看着像是币圈造的轮子呢?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1044263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX