https://github.com/GitHub-Laziji/shield
传统的防范暴力破解的方法是在前端登录页面增加验证码, 虽然能有一定程度效果, 但是用户也跟着遭罪, 验证码越复杂, 用户登录的失败率越高
于是最近我想了一个新的设计, 前端在登录时采用解密的方式获取密钥, 把密钥与表单以前发往后端, 用密钥来代替验证码
具体细节如下
随机字符串
和一个指定范围内的随机数
rstr+MD5(rstr+rint)
MD5(rint+rstr)
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, 用户察觉不到, 但是暴力破解的难道确增加了几千倍, 这意味这本来一个小时能破解的网站, 现在可能要一年才能破解
101
carlclone 2018-07-18 07:34:52 +08:00 via iPhone
简单问题复杂化,楼主可能缺 star 面试了
|
102
chuanqirenwu 2018-07-18 08:46:38 +08:00
请给出严格的数学证明,否则有可能存在一种方法使得你的方案与原方案没有差别。
|
103
master13 2018-07-18 09:02:16 +08:00
我有个问题,可能是我没看明白……
我暴破的时候,你这段前台循环碰密钥的方法已经给我了,我在本地碰好了在提交不行么……没必要通过提交来碰吧……具体比如用个 selenium 或者 phantomjs,应该很容易就可以在本地算出那个密钥吧 |
104
qdwang 2018-07-18 09:08:39 +08:00 via iPhone
lz 你的想法是可以的,现代不少防暴力破解的密钥生成技术就是需要大量时间或者内存。只是你的想法需要再精细一些,或者用一些现成可靠的密钥生成技术。
|
105
Antidictator 2018-07-18 09:19:59 +08:00
喜欢这个帖子,有理有据的讨论,收藏了。
|
106
mcluyu 2018-07-18 09:27:02 +08:00
楼主这个貌似就是给请求 body 加个签名? 然而方法还是暴露的貌似,这种方式可以用在 APP 上,因为加签方法隐藏在代码里看不到(反编译也可以针对这快代码做防止反编译的处理),但是对于前端页面没意思了吧,你的解密方法大家都可以看到了,人家模拟一遍就行了啊,你前端页面 JS 可以做到的事情,破解的人也可以啊。。。
|
107
Cheez 2018-07-18 09:30:24 +08:00 via Android
大哥,你的想法不错,但是直接限制 10 分钟内只能输入 3 次密码好像更好一点
|
108
SelFree 2018-07-18 09:36:14 +08:00
web 前端慢 hash 了解一下?
|
109
LeeSeoung 2018-07-18 09:41:30 +08:00
1、楼主的加密没任何意义,前端能做到的加密流程,任何程序都能模仿出来。
2、延时令牌方式 多线程下基本也没区别->改为限制 IP 时间段内访问次数 3、限制 IP 访问次数可以通过代理 IP 解决 4、引入页面人体行为检测(鼠标轨迹,按键等),发现机器行为不给接入,参考现在的拖动滑块验证码。 5、蜜罐,让攻击者以为正确获取到信息,实际上并没有,在蜜罐上多设陷阱,这种考验攻击者耐心。 |
110
lxy 2018-07-18 09:48:48 +08:00
算力验证码。老东西了。
|
111
wenzhoou 2018-07-18 09:50:14 +08:00 via Android
楼主是说:我不管我不管,我不听我不听。我这个就是有用,我这个就是好。😂
|
112
Clarencep 2018-07-18 10:09:43 +08:00
|
113
Clarencep 2018-07-18 10:15:34 +08:00
似乎改进下,顺便还能挖挖矿……
|
114
Citrus 2018-07-18 10:16:42 +08:00 via iPhone
大概看明白了楼主的意思,想通过强制前端进行高强度 MD5 计算来拖慢登陆重试频率。
想法简单来看没啥大问题,但是要知道 MD5 计算现在并不慢,如果用 GPU 集群的话,枚举延迟可能并不大。所以实际效果可能没有想象中那么美好,起码没比验证码好太多。。。 |
115
msg7086 2018-07-18 10:36:52 +08:00
只看你的描述:
1. 你的服务器端必须要保存生成的密钥,而且密钥无法防止离线破解。 也就意味着我可以先生成 1000 个密钥,统一计算完,然后一次发 1000 个登录请求上去。 2. 你的服务器端必须保存密钥,意味着可以直接进行 DDoS 攻击,直接打爆你生成密钥的存储系统。 所以到最后,你还是得在密钥生成系统上加上延时和保护。 那么也就回到一开始的解决方案:直接给登录系统加上延时和保护了。 |
116
338ccom 2018-07-18 10:53:50 +08:00
tumblr 的登录方式很不错
|
117
killerv 2018-07-18 11:09:17 +08:00
看了楼主的帖子和其他网友的跟帖,说下自己的理解。①有不少人理解错了,楼主的密钥算法是公开的,并不是靠这个来防止攻击,这点和常规 App 接口的签名算法并不是一个意思。②虽然如此,楼主这个还是意义不大,因为现在暴力破解网站用户名密码的瓶颈不在于计算,而在于 IO,打个比方,一个 web 应用的登录接口能承受的最大 QPS 是 1 万,计算机可以轻易做到 1s 内超过 1 万次的计算。
|
118
remnet 2018-07-18 11:41:57 +08:00
这就是一个 PoW 算法,几年前作为防止电子邮件垃圾的手段已经出现了。
Refer: https://en.wikipedia.org/wiki/Hashcash |
119
009694 2018-07-18 11:51:03 +08:00 via iPhone 1
bcrypt 了解一下。 前端将原始密码 bcrypt 加密 后端用其他快速加密方案。 同样能解决
|
120
snw 2018-07-18 12:35:17 +08:00
@jq8778
你这个设计体验极差的。我们公司有个同事输错了 N 次开机密码(全盘加密的),由于每次输错都会比上一次多等几倍时间,等他想到求助 IT 时下次输入密码要等十几个小时,于是当天就没法工作了。 最关键是攻击者完全可以对其他用户提交几次错误密码,导致其他用户无法登陆。 |
121
zhangyuting 2018-07-18 13:43:15 +08:00
@laziji 发现自己的想法是已有且被证实可用的,是一件很愉快的事情。
|
122
leoleoasd 2018-07-18 13:44:10 +08:00
|
123
galenzhao 2018-07-18 14:06:25 +08:00
pow 注册轮子
|
124
iyangyuan 2018-07-18 14:17:15 +08:00
这个就是慢 hash 嘛,故意增加算法难度,将 hash 的过程变慢,别忘了加上私有盐。
据我所知,这个好像是避免脱裤之后暴力破解的 |
125
keventseng 2018-07-21 15:56:26 +08:00
连续输入错误 X 次限制 X 分钟或者连续错误 X 次冻结,等用户重改密码恢复。会不会更简单些?
|