Java请求中关于如何避免防重放攻击

重放攻击介绍

防止重放攻击的方法是使用不重数

  1. 加随机数
    该方法优点是认证双方不需要时间同步,双方记住使用过的随机数,如发现报文中有以前使用过的随机数,就认为是重放攻击。缺点是需要额外保存使用过的随机数,若记录的时间段较长,则保存和查询的开销较大。
  2. 加时间戳
    该方法优点是不用额外保存其他信息。缺点是认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。但当系统很庞大,跨越的区域较广时,要做到精确的时间同步并不是很容易。)

我的做法是:
方法: 时间戳校验 + mac签名校验 双重验证
具体是:
在项目里面,当客户端请求我服务器的时候,会给我传递一些公共参数,比如客户端请求的时间戳,以及加密后的mac签名。
第一步: 我在拦截器里面拿到请求时间戳之后,转换为毫秒值,这时候我服务器端也会生成一个当前时间毫秒值,做差值比较
if((当前时间-请求时间)>60000 );//60秒
那就认为请求报文已经被拦截,正在攻击,说明此请求异常,结束请求。
如果是<60000毫秒 ,暂时认为是符合的(有疑问往下看),让请求继续往下走。

比较时间差值:

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

		long req_time = simpleDateFormat.parse("20190625093842").getTime();
		long now_time =  new Date().getTime();
		
		(now_time-req_time)>60000
 在步骤一的基础上, 已经判断了时间差值, 不安全,因为一秒钟就可能被请求很多次,所以还需要进行mac验证。
   这时候我借助了cache缓存器 (CacheManager类) , 思路是:
     把客户端请求mac签名作为key,客户端请求时间戳作为value,保存到cache里面,
     cache(mac, time, cache名字)  到cache里面。
     
      此时已经保存,然后下次客户客户端请求,先根据加密后的mac签名和缓存名去cache里面取值,如果能拿到请求时间key, 不为空,就可以断定正在被重放攻击(数据重复),需要拦截下来。如果根据时间戳拿不到mac,说明正常请求,然后把正常请求的mac,请求时间戳 保存到cache里面就行了。
      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190625111855656.png)
      timeToLiveSeconds="60":  缓存里60秒后会失效,这样就不会一直累加到缓存里面(当然有redis也可以借助redis).  大概就是这么个步骤。

Java请求中关于如何避免防重放攻击_第1张图片Java请求中关于如何避免防重放攻击_第2张图片
在这里插入图片描述

       											do-time:2019/6/25  
       											笔者:dk

你可能感兴趣的:(java,防重放攻击,防重放时间戳)