普通网站防暴力破解登录密码的新设计

2018-07-17 12:57:03 +08:00
 laziji

shield

前端防暴力破解的一个设计

Demo 地址

https://github.com/GitHub-Laziji/shield

描述

传统的防范暴力破解的方法是在前端登录页面增加验证码, 虽然能有一定程度效果, 但是用户也跟着遭罪, 验证码越复杂, 用户登录的失败率越高

于是最近我想了一个新的设计, 前端在登录时采用解密的方式获取密钥, 把密钥与表单以前发往后端, 用密钥来代替验证码

具体细节如下

设计

    randomString = Utils.getUUID();
    randomNumber = Utils.randomInt(range);
    privateText =  randomString + Utils.md5(randomString+randomNumber);
    privateKey = Utils.md5(randomNumber+randomString);
    let randomString = result.substring(0, 32)
    let valueString = result.substring(32)
    let answerString
    for (let i = 0; i < range; i++) {
        let s = crypto.createHash("md5").update(randomString + i).digest('hex')
        if (s == valueString) {
            answerString = crypto.createHash("md5").update(i + randomString).digest('hex')
            break
        }
    }

测试

经过测试 10000 次内 md5 加密前端用时不超过 300ms, 用户察觉不到, 但是暴力破解的难道确增加了几千倍, 这意味这本来一个小时能破解的网站, 现在可能要一年才能破解

优势

17043 次点击
所在节点    分享创造
125 条回复
34C
2018-07-17 13:55:16 +08:00
@laziji 你想多了,这点频率的下降,相比网络的耗时,几乎忽略不计,何况还可以多线程同时算
laziji
2018-07-17 13:56:45 +08:00
@34C 网络的耗时才是可以多线程大幅下降的
计算力的耗时 多线程没什么效果
34C
2018-07-17 13:57:22 +08:00
@laziji 多说无益,你直接上个 demo 让 v 友来试着暴力,无防御的、图形验证码的、你这个算法的,三者一起做对比
34C
2018-07-17 13:59:59 +08:00
@laziji 即便没有多一层你的算法,本来就会用多线程,但是网络带宽是有限的啊……
justfly
2018-07-17 14:00:46 +08:00
有用处。强制要求登录做一点无用功,正常的单次登录,用户做点无用功没什么影响,但是对于想要靠碰撞得到正确密码的这些无用功累加起来还是挺没效率的。

PS. 如果能把无用功换成某种有意义的东西就更好了,比如挖矿。。。
bearqq
2018-07-17 14:07:56 +08:00
让用户挖个矿吧,一个 share 提交一次,多和谐
laziji
2018-07-17 14:08:02 +08:00
@34C 对于无防御的后端 暴力破解的上限可能在于 电脑的带宽
但是用了这个明显一台电脑一秒钟能解出的密钥个数极其有限 (并且上限是后端可控制的), 这个时候 网络大部分时候都是空闲的
l12ab
2018-07-17 14:08:38 +08:00
Google 的验证码
laziji
2018-07-17 14:10:31 +08:00
@bearqq ....这是极端情况 , 可以后端调节 随机数的范围 得到一个合理的计算时间
xiaket
2018-07-17 14:11:11 +08:00
@justfly 这个思路好... 用户多了还能挣钱....
laziji
2018-07-17 14:11:32 +08:00
@l12ab google 的验证码是这样类似的吗 还不是很了解
panlilu
2018-07-17 14:13:44 +08:00
这属于一种 POW ……
mario85
2018-07-17 14:13:45 +08:00
图灵测试跟 pow 本质还是不一样的吧
ZE3kr
2018-07-17 14:15:00 +08:00
DeutschXP
2018-07-17 14:18:58 +08:00
毫无任何意义
0. 这种计算的成本几乎为零,你说的增加攻破难度,需要一年,只不过是因为无用功造成的时间成本。
1. 用户点击登录后,现在需要两次和后端交互,降低体验度。
2. 与其搞什么计算,不如直接延时发令牌,获取一次性令牌后再延时提交,用户点击登录按钮,显示请等待,后台开始忙活,把平时只需要 100ms 完成的登录验证,变成需要 3 秒才完成。这样一来,按照你的计算方法,本来几小时破解的网站,现在需要几年了呢,比你的一年还厉害。
而且我说的这个方法可以灵活配置。比如希望更长时间,直接延时 30 秒,就变成几十年才能破解了呢。如果登录等待过程改成一部电影的长度,好几辈子都破解不了。
tiztm
2018-07-17 14:22:49 +08:00
额,为了延长整个登陆的过程,你直接在后台写个 Thread.sleep(300)不就好了吗。。
34C
2018-07-17 14:25:43 +08:00
@DeutschXP 赞同,其实不用这么麻烦,如果楼主坚持增加所谓的算法时间成本,那在验证用户名密码的时候 delay 1s 再响应结果,都提升 100 多倍的耗时了,这个耗时还可以无视攻击者的电脑性能,天河一号来攻击都会需要 1s 才能知道结果
Ghkitg
2018-07-17 14:26:42 +08:00
这种有 Key 又有 range 的.全算一次做成彩虹表也花不了多久时间吧
Ghkitg
2018-07-17 14:29:02 +08:00
看错了,彩虹表不适用
fcten
2018-07-17 14:31:40 +08:00
不错的想法。对暴力破解的防护效果是有的,可以应用在一些安全性要求不高的场合,并且无需收集和记录用户的任何隐私信息。

虽然 JavaScript 的执行速度已经很快了,但是在这种 CPU 密集型的运算中,依然会比 C 慢上一百倍甚至更多。登录的场景不允许让用户等待太久,同时又要考虑到用户设备的硬件差异(例如一些比较老的智能手机)。最终抵御暴力破解的能力会打折扣。

就以楼主的例子来说,普通的台式机上 300ms,放手机上可能需要 3s,而攻击者用一台稍微好一点的机器,只需要 10ms。JavaScript 是单线程的,但是攻击者可以使用所有的 CPU 核心进行并发计算。假如攻击者使用的电脑有 16 个核心,就可以每秒尝试 1600 次。

要知道,合理的风控措施能做做到在支付场景下让用户使用 6 位数字密码。而这种 POW 策略必须搭配一个复杂的密码才能起到效果。

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

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

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

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

© 2021 V2EX