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

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 值进行比对?这样就不存在明文保存或传输用户密码的问题了。

4464 次点击
所在节点    信息安全
36 条回复
ryd994
2022-03-29 14:17:43 +08:00
@FrankHB “而一旦经过任何一个常规的 hash ,甚至不需要 salt ,这种 pattern 就被完全破坏,也就直接报销了一个重要的攻击向量。”
大家都用 md5 ,只要不加盐,还不是一样?常用密码的 md5 都可以随便查表反查了。甚至包括了键盘序列加生日和手机号等常见密码组合。

社工攻击的问题根源难道不是用户复用密码?只要这点不改,那无论你做不做客户端 hash 那永远都拦不住用户被其他网站钓鱼,再钓回你的服务。

好,就算你用加盐 hash ,那你服务端存什么?楼上已经有人解释过了,这个 hash 的结果成为了实质上的密码。

问题的根源其实是,密码登录从根本上就不是高安全的鉴权方式。安全要求稍高的服务应该用 2fa+密码策略要求定期改密码。要求更高的服务应该强制智能卡公钥登录。
银行用的 USB key 。或者完全独立的电子令牌。都是基于这个原因。
我厂的生产环境就是必须智能卡登入,而且不是日常查邮件的智能卡,而且还要在专用电脑上连专用 VPN 才能连上。要是简单的密码二次 hash 就有用,我厂的安全团队是傻吗?

@ruixue 你觉得这是善意,但是这真的有益吗?
如果你后端服务器的密码库泄露了,假设你用的是前端 hash 一遍后端又 hash 一遍的做法。请问要穷举 128 位的 hash 容易还是穷举任意随机密码容易?
二次 hash 只会减小值域,不会增加熵。因为 hash 一定是单向的。
ryd994
2022-03-29 14:21:14 +08:00
@ruixue 如果你不信任你的 CDN ,你完全可以用独立域名处理登入。很多大网站包括银行都是这样做的。
需要更高安全性的部分,自己管理,和其他系统解耦。反正性能也不是最重要的因素,又不是每天都需要反复登入。这种系统有必要上 CDN 吗?
GBdG6clg2Jy17ua5
2022-03-29 14:58:27 +08:00
个人觉得旧苹果事直接明文传的密码。到了服务端再分割的。或者是,有啥动态更新的吧。
ruixue
2022-03-29 15:12:03 +08:00
@ryd994 Keep relax~ 反问句三连差点噎到我了,我们是在讨论不是在争吵,语气没必要那么盛哈,心平气和有助于身心健康^_^

Anyway ,每次出现拖库事件,在已经造成损失的前提下,用户还是更希望泄露的是加了盐的 hash 而不是明文密码吧。上面那位 V 友的意思也差不多,比方说有人在 V2EX 用的密码是 Sbkill1rQlb6xv2 ,那么假如泄露了明文密码,撞库攻击者很可能会按照规律(十步杀一人千里不留行+网站名缩写)猜测这个人在 cloudflare 用的密码是 Sbkill1rQlb6xcf
ryd994
2022-03-29 15:34:29 +08:00
@ruixue 脱库的问题与是否进行客户端 hash 无关
密码当然应该 hash 储存,这是没问题的
但是基于 TLS 或者 CDN 不完全可信,来证明客户端 hash 可能有益,那前提就不应该使用不可信的 CDN 。登入系统的日志属于安全日志,本来就不应该允许非安全部门访问。
事实就是没有哪个大厂的网站在使用客户端 hash 。如果客户端 hash 真的这么有效,那大厂的安全审计为何不采用?
agagega
2022-03-29 15:52:52 +08:00
如果你的信道不是 HTTPS ,那手动给密码做散列也没用,因为理论上你的 JS 文件都是可能被别人注入过的
ruixue
2022-03-29 16:56:56 +08:00
@ryd994 嗯,不明文储存密码肯定是有意义的

不过我从来没说过 TLS 是“不完全可信的”,相反,我对 TLS 的安全性充分信任,即使有可能出问题那也是在 TLS 之外,比如 CDN 、负载均衡器或网页服务器解密流量后。至于客户端 hash ,我还是觉得不能一竿子打死。像 github 和 twitter 这种大厂都出现过日志泄露明文密码的漏洞,所以也不能说客户端 hash 是完全的无用功,毕竟可以减少整个链路的攻击面,万一日志配置有误也不会造成明文密码泄露,相当于多加了一道保险

https://www.sohu.com/a/230309592_465914
https://www.sohu.com/a/230826659_175007

这些大厂之所以不这么选择可能是基于成本的考量,认为这样带来的收益远低于增加的成本,但并不能得出这么做就没有任何意义的结论
laozhoubuluo
2022-03-29 19:17:15 +08:00
@xuanbg
@ZE3kr
@ruixue
@lakehylia
@jobmailcn

1. 实现这个在 C/S 框架下也是要改服务端的。另外要注意一个安全问题,如果是两层 hash 的模式下攻击者不拥有用户的明文密码而拥有 内层 hash(password) ,那么攻击者也可以构造一个合法登录请求,让服务器无法分辨用户是否知道密码明文,这么改相当于额外构成了一个安全隐患,本来泄露的是 hash 过的密文结果能登您这个网站了。

2. 另外按照 1 这么改的话实际上密码是不能加盐或者盐必须直接发给客户端,这样的话又拉低了密码的安全系数,所以还不如明文传输完了让服务器那边能安全的给密码加盐,加盐可以提升脱裤场景下的攻击难度,而且由于盐不一样导致泄露的 hash 是无法直接复用到其他网站的。而且当前的最佳实践是哈希算法+一个密码对应一个盐。如果不用哈希算法的话那更没意义,毕竟攻击者拿到密钥或者私钥直接就能拿到密码明文了,安全性不如当前最佳实践。

3. 如果必须要做二次加密的话,合理的方式是使用 RSA 等非对称算法,服务器发公钥给客户端,客户端用公钥加密密码、OTP 等需要加密的数据之后再传给服务器,服务器用私钥解密。这个流程相当于 TLS 握手,所以意义很小。费这么半天劲只解决了低概率的 CDN 以及开发者错误记录(正常实现是绝对不会记录的,而且如果他恶意投毒的话是没意义的,因为不管是 CDN 还是开发者都可以直接在网页里面插入自己的代码从而直接把用户输入拿到),是一个成本极高收益极低的安全防护手段。
3dwelcome
2022-03-29 19:56:54 +08:00
md5 函数分 md5_update 和 md5_final ,可是有些 hash 函数,这两个函数是同一个。

也就是说,hash(password)+hash(str) = hash(password+str)
chinvo
2022-03-29 20:05:28 +08:00
月经帖了...

实际结论就是不需要前端造轮子“加密”.

依赖 TLS 保障安全性.

不信任 CDN 的话, 那 CDN 也同样有能力解码或者重放前端的“加密”或 hash, 因为对后端来说, 传递过来的值就是实际有效值. 前端 hash 之后被 CDN 或者其他中间人拿走, 一样造成和明文同样的风险.

至于日志泄漏, 纯属开发或者配置问题.
ryd994
2022-03-30 00:32:34 +08:00
@ruixue 成本?我没看出这事有任何成本。不是完全在客户端实现吗?老用户可以强制下次登入改密码。
CDN 日志泄密,问题难道不是登入域名压根就不该走 CDN ?
首先,请你澄清一下你的协议。服务器储存什么形式的密码。客户端发送什么形式的密码。是否加盐。
提醒你,全加一样的盐等于不加盐。
ruixue
2022-03-30 09:56:46 +08:00
@ryd994 #17 说客户端 hash 密码造成开发测试的不方便就是一种成本,你说没有任何成本,你俩要不先打一架

至于 CDN 日志泄密,又不是只有 CDN 才会有日志安全的问题,自己的服务器也有啊。上面发的 github 和 twitter 明文密码泄露的新闻只要点开过也不会认为这两个的漏洞是出在 CDN 的日志上

客户端加盐也可以不同的账号根据算法采用不同的盐

都说了语气没必要那么盛,又是反问句三连。你平时是当领导呵斥下属习惯了还是怎么。。咄咄之势你还是留给他们吧,恕不奉陪
FrankHB
2022-03-30 13:01:10 +08:00
@ryd994 要防止撞库的自动化攻击只要避免完全一样的口令即可。能反查的仅限全文匹配的没加盐的。
而且,规模受限;比如生日这个空间不够大够放表里,那么手机号呢?

另一方面,实践中用户可能使用的简单生成策略,比如把相对容易反查的数据和某个无法预测但是攻击者可以人工推断的前后缀串接,就能让反查失效。这个也算是盐,不过是加在了用户的脑子里罢了。
如果没 hash ,这仍然是一种明显的复用而会受到威胁;不巧的是,这种编码方式实际还真是挺顶用的,最起码对大多数人来讲比全随机串好记得多。

用户为什么要复用密码?因为实现成本低。这又是因为,密码这种形式,要求用户自己实现密钥的重现。
只要 UI 上需要用户日常记忆的密码(而不是你说的所谓“高安全的鉴权方式”)的情况普遍存在,“复用”基本就是刚需。但是想要高安全的鉴权方式替代,如何普及?多出来的成本你搞定?
所以说,问题的根源并非鉴权方式不够安全,而是欠缺鉴权的服务等级,无法落实对合适的路径使用合适的鉴权机制。对不重要的账户,就应该避免要求高成本的鉴权方式,而不是逼着用户平摊鉴权成本自己搭建可能对某几个关键路径不够安全的服务。
但不重要也只是相对而言,并不是说无所谓了。所以即便有智能卡的情形你能说 hash 没用,没智能卡就弃疗的思路显然是不对的。这种情况下,有没有多一层 hash ,安全性不可能一样。
特别地,考虑到这样做的主要理由正是应付直接推高用户记忆成本的被大量滥用的密钥策略,你要是想甩锅给用户这样就是安全习惯不好,是用户的错,此路更加不通。

而如果真要提高安全性,那么只有方案也是不够的。现有基础设施无法提供的安全机制的实现,服务方也应该一并提供——比如银行可以提供 USB key ,但不应该把设计甩给用户让用户自己造一个,造不出来就后果自负。
所以有没有 hash 不可忽视的情形下,hash 应该由服务方提供而非用户自己变通。

至于“hash 的结果成为了实质上的密码”,只要被截获的信息不能被反查出明显特征,这就不是用户需要关心的。服务器用哪个 hash 都不提高用户保障安全性的成本,这才是所谓的“一样”。因为成本原因,智能卡可以没有,这种“一样”反倒是优先该有的。
FrankHB
2022-03-30 13:15:40 +08:00
@FrankHB 注:我不清楚 21L“包括了键盘序列加生日和手机号等常见密码组合”具体是指什么,但是要全覆盖,光是手机号(杠一点,其实还有国际区号)都有些难度,更不用说“特定前缀+手机号+特定后缀”的组合了。注意这些 pattern 是可以每个凭据都有变化的,没法大规模自动撞库。
FrankHB
2022-03-30 17:00:36 +08:00
@ryd994 “脱库的问题与是否进行客户端 hash 无关”,这显示出你的理解的偏差。
虽然不直接相关,但脱库得到的内容的使用方式可以类似,使用 hash 的动机也一致。
而这种敏感数据除了脱库还可以通过劫持客户端通信来获取(于是你说的对策反而不够用)。即便没像服务器被攻击那么瞩目;就受害者看,威力一点都不小。

对抗这种攻击,要做到攻击者本人通过唯密文攻击的方式无法分辨出敏感数据中可能带有的感兴趣的特征,至少不能一眼认出来。
至于是不是正经的加密,其实相对无关紧要,所以一个像样的 hash 都行。(当然,得别被随便能反查。)
若有这种客户端 hash ,攻击者要实现相同的效果,除非强行爆破 hash ,基本还需要多攻破客户端系统基础设施。
因为系统厂商普遍盯得比较紧,后者一般比单纯让 TLS 失效(各种意义上)难得多,或者至少没法长期利用。
使用非公开 hash 算法时,强行爆破成本很难预期。
首先,若攻击者无法获得程序取得其中的算法,这就无解。(当然,网站就弃疗好了,毕竟浏览器属于公共白嫖设施。)而想要通过攻击得到能分析的样本,也需攻破基础设施。
虽然要强行作为加密系统,这明显不符合 Kerckhoffs 原则而影响适用性,但是:
(1)说了用 hash 就强调不需要加密,虽然其实加密也能用,但拿来恶心攻击者这就杀鸡用牛刀了;
(2)让攻击者知难而退这种更普遍的方法论甚至就不算是密码学的原理;反倒是使安全性和加密信道的密码学强度正相关的实践,只是其中的一种特例罢了。
其次,即便有样本能逆向,非公开算法自动化手段相比查表之类可以说是极弱,光分析客户端行为就够普通攻击者喝一壶的了。
再退一步,能逆向成功甚至能直接看源码,之后怎么破还得密码分析,也根本没通解。

硬从理论角度讲,这里能保障的安全性的定义根本不同:系统的安全性不是以存在确定明文(以及加密和解密)作为前提来定义的密码系统的保密性(不论是信息论安全性还是计算安全性),而是使从信息中提取任何攻击者感兴趣的函数的计算开销的度量(若资源确定,也可以用成功概率)。
一些假设:(1)攻击成功前攻击者无法预先给出区分是否有兴趣(或度量利用价值)的算法;(2)(有兴趣的信息足够少)任意不依赖内容的选取子集符合兴趣的方法的概率现实地任意接近于 0 ;(3)人基于现实不可描述的、依赖个体对敏感信息特征识别的经验,有一定概率(使用未指定的未知算法)超越任意机器提取信息的能力,特别地,蕴含筛选出提高成功率的正确决策方法。
基于(1)和(2),任何现有机器在都不能分辨被 hash 隐藏的特征是否符合攻击者的兴趣(否则这机器得能自主定义什么叫兴趣判断什么值得继续爆破,基本就是强 AI 了);于是,结合(3),确定时间内,攻击的成功严格依赖于人。
那么 hash 的作用就是专门欺负人:消除特征,添加噪音,让人肉攻击者的经验失效,概率无限接近于 0 ,成功提取信息的代价任意地大,从而实现不可攻击。

是不是值得保障这种安全是另一回事,但这种安全性的现实存在是确定的。(并且很容易有木桶效应。)
nothingistrue
2022-03-31 09:45:57 +08:00
@ruixue 我接着看了你后面的对话,发现你是一种啥都往最好做的想法,俗称“烂好人”。这个想法在事情小的时候是真好人。但是,哪怕是非常小的成本,也是会富集的,当事情大的时候,啥都想做好就会变成啥都做不好,成了烂好人。客户端哈希或者加密对于小系统(或者个人)来说确实成本很微小,但是对于几十甚至几百人开发的大系统,成本富集到管理者那里就会很庞大。这个时候管理者就要做均衡了,极为重要的系统不止要做客户端密码哈希,客户端非对称加密都要上,甚至可能还要上物理证书(俗称的加密狗),但是面向大众用户的客户端,上个 HTTPS 就够了,哈希都不要做。

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

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

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

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

© 2021 V2EX