接口鉴权 & 重放攻击

在实现接口鉴权功能的时候,我们应该防止出现重放攻击,可以借助 OAuth 的验证思路来解决。

一、概念:

接口鉴权:对外开放的接口在使用的时候须鉴定访问者是否有权访问接口,为了防止API调用过程中被恶意篡改,调用任何一个API都需要携带请求签名,签名不合法的请求都将被拒绝。

重放攻击(Replay Attacks):顾名思义,重复的会话请求就是重放攻击。可能是因为用户重复发起请求,也可能是因为请求被攻击者获取,然后重新发给服务器。

二、重放攻击的防御方法

1、加时间戳:请求时token加上客户端当前时间戳,同时签名(签名是为了防止会话被劫持,时间戳被修改),服务端对请求时间戳进行判断,如超过一分钟,认定为重放攻击,请求无效。

缺点:时间戳无法完全防止重放攻击。未认证系统还是可以在这一分钟的 token 失效窗口内,通过截获请求、重放请求来调用接口。并且认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。但当系统很庞大,跨越的区域较广时,要做到精确的时间同步并不是很容易。

2、加序列号(流水号):
在客户端和服务端通讯时,先定义一个初始序号,每次递增。这样,服务端就可以知道是否是重复发送的请求。

缺点:但是一旦攻击者对报文解密成功,就可以获得序列号,从而每次将序列号递增欺骗认证端。

3、加随机数(nonce):该方法优点是认证双方不需要时间同步,双方记住使用过随机数如发现报文中有以前使用过的随机数,就认为是重放攻击。

缺点:缺点是需要额外保存使用过的随机数,若记录的时间段较长,则保存和查询的开销较大。

4、挑战与应答的方式:
客户端请求服务器时,服务器会首先生成一个随机数,然后返回给客户端,客户端带上这个随机数,访问服务器,服务器比对客户端的这个参数,若相同,说明正确,不是重放攻击。

这种方式下,客户端每次请求时,服务端都会先生成一个挑战码,客户端带上应答码访问,服务端进行比对,若挑战码和应答码不对应,视为重放攻击。

5、HTTPS防重放攻击
对于HTTPS,每个socket连接都会验证证书,交换密钥。攻击者截获请求,重新发送,因为socket不同,密钥也不同,后台解密后是一堆乱码,所以HTTPS本身就是防止重放攻击的,除非能复制socket,或者进行中间人攻击。

三、实现

为了防御重放攻击,我在实际开发中见到的方法是增加token参数,举个例子:

1、如果某应用需要请求服务器端接口,需要服务器端给分配一个app_key和一个app_secret给这个应用,并且服务器端需要备份一份,方便后续查找;

2、为了防止重放攻击,在参数中加入时间戳等参数(可参照上面防御方法);

3、然后使用加密算法MD5或者SHA进行加密,生成token,在请求的URL中加入这个token参数,生成方式如下;

SHA(app_key=abc&app_secret=123&timeStamp=1669855515)
URL:https://xxx.xx.com/index.do?app_key=abc&token=xxx&timeStamp=1669855515

4、服务器端收到请求后解析出参数:app_key、token、timeStamp;

5、根据时间戳timeStamp判断请求是否失效(我们暂定为一分钟),超一分钟为失效,如失效直接拒绝;

6、然后从服务器端根据app_key获取app_secret;

7、使用app_key、app_secret、timeStamp三个参数生成服务器端token,方式同上;

8、比较服务器端token和请求参数中token的是否一致,一致就鉴权通过,否则拒绝。

你可能感兴趣的:(接口鉴权 & 重放攻击)