1
shoaly 2017-07-29 16:10:49 +08:00
客户端传给服务器
?nonstr=md5(时间戳 +随机数+ 特定字符串)&time=时间戳&random=随机数 服务器端: 验证 md5(用客户端传入的时间戳+ 随机数+特定字符串) 与 nonstr 对比 验证是否是客户端的请求, 然后将这个 nonstr 存入缓存当中, 同一个 nonstr 如果已经存在, 则为重放攻击 |
2
shoaly 2017-07-29 16:11:42 +08:00
补充 1 天之后的重放, ..时间戳能对比出来啊.... 客户端确实和服务器端时间不一致, 但是 差不了几秒.
|
3
retanoj 2017-07-29 16:16:38 +08:00 via Android
为什么时间戳无法保证和服务器一致? 难道不是在用格林尼治时间吗? timestamp 加签名应该可以解决重放了
|
4
des 2017-07-29 16:31:03 +08:00
时间差?就不能请求获得服务器时间,然后基于这个时间戳校正吗,如果出错就先获取一次时间戳再请求一次。
总不能客户端的一分钟被人偷走一秒吧? |
5
nealv2ex 2017-07-29 16:39:50 +08:00
单纯的放重放来说 ,全不用不管与服务器的差值,只看时间戳就可以,时间是线性增大,不会变小,如果不变或者变小了,就有问题。
收到请求,校验时间戳必须比上一次 这个 session 的提交的时间戳大。 比如 第一次是 0,第二次 1 在过滤重放攻击这个条件下,这 2 个值都是合法的。 |
7
danielmiao 2017-07-29 17:02:28 +08:00 1
令牌桶,客户端请求的时候判断超过 x 分钟,更新令牌;
然后旧令牌的失效时间为,更新令牌的时间+[0.2, 1] * x,以保证正常的并发请求; 简单的说就是动态发放令牌,有效令牌为当前发放和有效期内的旧令牌,最好使用 cookie,保证对页面的无侵入 |
8
danielmiao 2017-07-29 17:03:22 +08:00
@nealv2ex 这个方案有个问题就是 ajax 并发请求的时候,后发先置的问题
|
9
paradoxs 2017-07-29 17:11:37 +08:00
参照 google authy 的验证机制, 把随机数发生器内置在前端就行了。
|
10
nealv2ex 2017-07-29 17:42:35 +08:00
@ho121 改时间,就不是 *重放* 攻击了。
@danielmiao 这里只解决 *重放*,后发先至是其他问题。 不过请思考一下,后发的请求已经到了,那么是不是说, 客户端取消了先发的请求,要不然哪里来的后发请求, 那么我只处理后发的请求,不处理先发的请求应该是合理的。 |
11
lemayi OP 感谢各位的解答!非常感谢!
@nealv2ex 的回答,之前我也有考虑。但是确实会有并发,后发先至的问题。既然是并发,先发,后发的请求都肯定是合理。如果参考你的处理的方式,肯定就排除掉了正常的请求。 @shoaly @des @retanoj 因为是前后端分离的 web 项目。js 生成的时间戳应该是本地时间。所以这个时间是很有可能和服务器不一致的。跨时区,篡改等。我之前做过测试。在服务器端放个含时间 js 的 html。然后去请求。确实打印出来的时间是我本地的时间。我电脑改了。显示的时间也改变了。其实我问的问题,主要就是纠结于此。如果是在后端的程序请求 api 那就没这个问题。我可以让客户端设置成和服务器端的一致。 @danielmiao 的方式令我思路大开。因为当前用的是 jwt 的 token。那么我可以让前端,每 30 分钟就去重新刷新获取新的 token。然后配置每次请求用 nonstr 来防止重发。记录 30 分钟内的 nonstr 集合。不在这个集合里面就是正常请求。这样即使过了 30 分钟,发起重放。实际上我的 token 已经变了。就没这个问题了。也不会有时间戳一致的问题了。 |
12
plantain 2017-07-29 18:23:42 +08:00
标准方法难道不是 https ?
|
14
motian 2017-07-29 18:50:26 +08:00 via iPhone
时间戳本身是跟时区无关的,你在东八区和零时区,不同的是日期时间,时间戳是一致的,客户端和服务端的时间差问题可以进行定期的时间校准。
|
15
retanoj 2017-07-29 22:27:26 +08:00 via Android 1
不过 lz,jwt 里有个字段是标识请求仅一次有效的啊,好像是 iat ?可以参考一下
|
16
whileFalse 2017-07-29 22:29:40 +08:00 via iPhone
你要防止的是啥?中间人重放的话上 https 就行
|
17
lianz 2017-07-29 22:34:42 +08:00
timestamp=int(timestamp()/30),这样服务器客户端时间误差 30 秒内就可以满足条件。
当然请求签名是一定要做的,不然一切白费。 |
18
voocel 2017-07-29 22:45:25 +08:00 via iPhone
请问用的是哪个 jwt 包
|