服务商允许用户在旧版系统密码输入框中同时输入 [密码]+[随机验证码] 完成身份验证,是否意味着服务商明文保存或传输了用户的密码?

2022-03-29 02:07:27 +08:00
 dLvsYgJ8fiP8TGYU

看到 https://v2ex.com/t/843372 ,有个疑问: 假设服务端只有 [密码] 的 hash 值,也知道 [随机验证码] 的明文,如何在没有明文密码的情况下,验证 [密码]+[随机验证码] 整体的 hash 值符合预期?

还可能是服务端通过 UA 或其他方式判断这是旧版系统,于是把用户输入值的后几位数裁掉,认为是验证码。但这也意味着客户端发送的不是 [密码]+[随机验证码] 整体的 hash 值,而是这段信息的明文?在实践中这样做,是不是把数据安全完全依赖于 HTTPS 的安全性,面对 MITM 就全泄漏了?

是否存在一种 hash 算法,支持通过客户端发送过来的 hash('password'+'2fa') 的结果,和服务端已知的 2fa 这段明文,推算出 hash('password') (用户密码的 hash 值),进而与数据库中存储的密码 hash 值进行比对?这样就不存在明文保存或传输用户密码的问题了。

3697 次点击
所在节点    信息安全
36 条回复
XiLingHost
2022-03-29 02:11:22 +08:00
为什么不客户端直接传 hash('password')+plain('2fa')
Building
2022-03-29 02:13:11 +08:00
发两个 hash ,一个密码 hash ,一个(密码 + 验证码) hash 不就完了吗
dLvsYgJ8fiP8TGYU
2022-03-29 02:13:42 +08:00
@XiLingHost 我是这样想的,因为是旧版系统,没法在后来推出双重验证后修改传输机制。
你说的也完全可能,那看来是存在热更新,修改了传输机制
ryd994
2022-03-29 02:53:58 +08:00
用户输入的密码就应该是明文(+TLS ) 传输

客户端 hash 没有意义。hash 后的内容成为了实际上的密码。如果我有能力 mitm 你的 tls ,我就有能力重放这个 hash 。结果上这个 hash 就是密码了。

就算服务端指定一个随机数做盐也还是没用。我可以 mitm 改掉你的客户端输入框,取得密码原文之后再加上盐来 hash ,再传给你。

以 TLS 可能失效为前提,那不就等于没有 TLS ,等于是明文?但是又想用某个办法来保护传输中数据,那不就是重新发明 TLS (或者打败 TLS )?这就是密码学民科啊

TLS 的安全性当然需要研究,但那是专业密码学人士的问题。你作为 app 开发者,也就是 TLS 套件的用户,需要做的只有按照推荐设置配置你的 TLS 服务,然后及时更新 TLS 软件库而已。
GeruzoniAnsasu
2022-03-29 03:02:53 +08:00
OP 看到浏览器登录时 post 了它的密码明文时不得吓得几晚上睡不着……

在加密信道中传输的内容怎么算「明文」,你的系统输入框还「明文捕捉」了你的密码输入不是
Zhouisme
2022-03-29 03:03:05 +08:00
我记得 Apple id 可以在密码后不空格加随机认证码。
应该是本地分割验证码和密码,毕竟后六位就一定是验证码,然后分别哈希传回。
ruixue
2022-03-29 03:40:30 +08:00
@ryd994 考虑到第三方 CDN 和网页服务器的日志有可能会不脱敏地记录完整请求,浏览器先加一层 hash 也不是说就完全无意义

服务器不储存明文密码也是有意义的,万一发生数据泄露可以减少撞库攻击的概率(只要不同的服务使用的混淆 salt 不一样),当然最好的防范措施还是要求用户一站一密
xuanbg
2022-03-29 06:25:58 +08:00
就不能 hash(hash(pw) + code)的结果传给服务端验证吗?为啥需要保存密码明文?
ZE3kr
2022-03-29 07:58:12 +08:00
你在浏览器里用纯 HTML 实现的登录,传的密码肯定是明文,去 Console 里看就能看到。因此 Chrome 、Safari 等浏览器只要遇到非 HTTPS 网站填写表单,或者是非 HTTPS 网站有密码输入框,就会警告不安全。

传输时明文不等于数据库里存明文……

> 在实践中这样做,是不是把数据安全完全依赖于 HTTPS 的安全性,面对 MITM 就全泄漏了?

是的。所以 HeartBleed 漏洞一出密码全泄漏。此外 CDN 也能看到密码,如果 CDN 出了 Bug (如 Cloudflare 之前默认开启的 HTML 压缩),密码也泄漏。为什么依然要这样做?个人觉得依赖 HTTPS 更安全,因为这部分是系统 /浏览器实现的,会经常更新,用的非常广泛。自己实现的 Hash 五花八门,未必就安全,而且还要求客户端与服务器实现一样的 hash 。一些服务器依赖的硬件加密模块客户端未必支持。而且如果此时客户端存 hash(password)服务端也存 hash(password),那就和存明文密码没有多大区别了。如果此时客户端发 hash2(password),服务端存 hash1(hash2(password)),那这又和客户端发明文密码,服务端存 hash 有啥区别?中间人拿到 hash2 一样破解你。

如果客户端设置密码的时候发明文密码,登录的时候发 hash2(password, time),能稍微安全一点,但这样还不如 2FA ,因为这样只要拿到了 password ,就能算出来要发送的结果。
Tink
2022-03-29 08:01:40 +08:00
这说明不了吧
ZE3kr
2022-03-29 08:05:17 +08:00
@xuanbg 这样就需要服务器存 hash(password)。这样的问题就是一旦被拖库,你就拿着数据库里拖出来的 hash(password)和数据库里 TOTP 的 Passphrase ,就能直接算出来 hash(hash(pw) + code)了……反而更不安全

相比要求传输明文密码的,你从数据库里拿出来的 hash 反推明文密码还是有难度的
ZE3kr
2022-03-29 08:06:53 +08:00
> 是否存在一种 hash 算法,支持通过客户端发送过来的 hash('password'+'2fa') 的结果,和服务端已知的 2fa 这段明文,推算出 hash('password') (用户密码的 hash 值),进而与数据库中存储的密码 hash 值进行比对?这样就不存在明文保存或传输用户密码的问题了。

这种事情不该交给 hash 去做,因为 hash 本身就不是加密解密用的。应该交给正经的加密算法去做
FrankHB
2022-03-29 08:15:23 +08:00
@ryd994 你的分析有个明显的缺陷:完全假定对凭据的攻击是机器进行的。然而攻击的原理并不一定是密码学,至少还可能是社会工程学。这包括人可读而机器不可读的口令——一个常见的应用是,根据“密码”中包含的 pattern 猜测用户设置口令的偏好(比如是否包含某种明显像是生日之类的个人可识别信息),缩小相关的其它需要碰撞的敏感信息的解空间,显著优化攻击效率。而一旦经过任何一个常规的 hash ,甚至不需要 salt ,这种 pattern 就被完全破坏,也就直接报销了一个重要的攻击向量。
lovelylain
2022-03-29 08:17:27 +08:00
可以传输 hash(password+2fa),password 在数据库是对称加密存储的,验证时先解密出明文再同样算 hash(password+2fa)
xuanbg
2022-03-29 08:34:20 +08:00
@ZE3kr 你都拖到库了,那么安全就只有加密 hash(pw)一途可解。
codehz
2022-03-29 09:02:19 +08:00
中间完全不传输密码的验证方案也不是没有,你们电报就是用 srp 的算法确保即使全部传输数据都被解密攻击者也无法得知原始密码((顶多暴力破解,但这种情况啥协议都防止不了)
nothingistrue
2022-03-29 09:16:22 +08:00
@ruixue #7 一、CDN 不能直接获取到明文,除非你让它获取。二、服务器记录日志不脱敏,是程序设计问题,并且在开发期就可用解决,那这个就不能用来作为运行期安全措施的论据。客户端加密或者 hash ,那是肯定有意义的,但是要不要实施这种措施,是要跟成本做对比的。当前,密码泄露的风险,真得没有客户端 hash 密码造成开发测试的不方便的成本大(服务器密文保存密码更多的是防止撞库,这也能解释为什么服务器不能只是单纯的 hash 密码,而必须先加盐再散列)。

@dLvsYgJ8fiP8TGYU 只有超高安全级别要求才会在客户端加密密码,通常都是:客户端和网络传输明文,服务器端存储散列码(密文),通过 HTTTPS 来保证网络传输阶段不被窃取。此外,就算你这个系统的安全级别是要求客户端加密密码,对于没法升级的旧系统,也得允许降级成客户端不加密的方式。
lakehylia
2022-03-29 09:39:36 +08:00
如果不想让中间人攻击拿到 TLS 传输的明文密码,那确实可以明文传输 hash 后的明文密码,服务端以 hash 后的明文密码为用户密码,但是挡不住你这个账户泄漏了。
ruixue
2022-03-29 09:41:09 +08:00
@nothingistrue 现在很多第三方 CDN 和负载均衡器都是在他们那边实施 SSL 卸载,方便实现缓存和页面规则,不是说想让它不获取就不获取的

不明文传输和保存用户的密码确实并没有给服务本身带来什么额外的安全性,但是却能有效降低数据泄露后用户的其他服务被撞库的风险,这对于很多常用密码走天下的用户来说是一种善意,很多服务提供者愿意提高一些成本来释放这种善意,不能说他们就是傻
julyclyde
2022-03-29 13:15:50 +08:00
你的分析是正确的

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

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

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

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

© 2021 V2EX