1、背景需求
针对公司原本的接口,再不改动原本业务逻辑的前提下进行重放攻击防御;
2、重放攻击原理
重放攻击是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。简单来说就是,发送一条已经执行过的消息,通过系统的身份认证,再次执行,达到攻击的目的;
3、防重放攻击解决思路
时间戳
“时戳”──代表当前时刻的数 基本思想──A接收一个消息当且仅当其包含一个对A而言足够接近当前时刻的时戳 原理──重放的时戳将相对远离当前时刻 时钟要求──通信各方的计算机时钟保持同步 处理方式──设置大小适当的时间窗(间隔),越大越能包容网络传输延时,越小越能防重放攻击 适用性──用于非连接性的对话
序号
通信双方通过消息中的序列号来判断消息的新鲜性 要求通信双方必须事先协商一个初始序列号,并协商递增方法
提问与应答
“现时”──与当前事件有关的一次性随机数N(互不重复即可) 基本做法──期望从B获得消息的A 事先发给B一个现时N,并要求B应答的消息中包含N或f(N),f是A、B预先约定的简单函数 原理──A通过B回复的N或f(N)与自己发出是否一致来判定本次消息是不是重放的 时钟要求──无 适用性──用于连接性的对话 重放攻击是对协议的攻击中危害最大、最常见的一种攻击形式。
4、攻击防御实现思路
由于业务已经成型,所以本次的解决方案采用了时间戳+提问与应答的方式进行防御;
注意事项:
此方案需要依赖客户端的时间戳,上送时间为东八区时间;
5、AOP前置增强,防御重放攻击
1、创建自定义注解,用于标注是需要防御的接口的,
2、配置aspectj切面,实现防御的具体逻辑
3、定义自定义异常,在认证失败后抛出异常
4、配置切面
自定义注解(preventReplayAnnotation)
package com.xx.xx.acc.biz.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时依然存在
@Target(ElementType.METHOD)
@Documented
public @interface PreventReplayAnnotation {
}
切面
/**
* @FileName: PreReAttacksInterceptor$
* @Author: ips$
* @Date: 2018/12/6$ 14:28$
* @Description: $
*/
package com.xxx.xxx.access.biz.eaccount.interceptor;
import com.xxx.xxx.access.biz.util.ReqSignUtils;
import com.xxx.xxx.common.consts.Constants;
import com.xxx.xxx.common.consts.SystemConstants;
import com.xxx.xxx.common.exception.BizException;
import com.xxx.xxx.common.exception.PreReAttacksException;
import com.xxx.xxx.common.msgcode.MessageCode;
import com.xxx.xxx.common.utils.DateUtil;
import com