java添加时间戳防止重放攻击
程序员文章站
2022-05-05 15:16:38
...
每次HTTP请求,都需要加上timestamp参数。因为一次正常的HTTP请求,从发出到达服务器一般都不会超过60s,所以服务器收到HTTP请求之后,首先判断时间戳参数与当前时间相比较,是否超过了60s,如果超过了则认为是非法的请求。
直接上代码:
js
在页面引入aes.js,在请求头部中传入加密的时间戳
$.ajax({
cache : true,
type : "post",
headers : {
dateStr : encrypt(new Date().getTime())
},
url : "${ctx}/sysrole/save",
function encrypt(value) {
//**
var secretKey = CryptoJS.enc.Utf8.parse("asdfghjk18537gbe");
var srcs = CryptoJS.enc.Utf8.parse(data);
//加密
var encrypted = CryptoJS.AES.encrypt(srcs, secretKey, {
mode : CryptoJS.mode.ECB,
padding : CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
定义一个过滤器在doFilter方法中加入下面代码
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request1 = (HttpServletRequest) request;
String s = request1.getRequestURI();
logger.info("请求URL:"+s);
if (s.contains("/save")){
String dateStr = request1.getHeader("dateStr");
//解密时间戳
String decrypted = decrypt(dateStr);
if(StringUtils.isBlank(dateStr) || StringUtils.isBlank(decrypted)){
logger.info("请求参数错误");
return;
}
//一般抓包攻击请求时间都大于60秒,所以超过60秒拦截
if(difference(new Date(), decrypted) > 60){
logger.info("请求超时");
return;
}
}
}
public static String decrypt(String encryptHex){
//** 必须与前端js的相同
String key = "wertgbyhnufbge74";
//构建
AES aes = SecureUtil.aes(key.getBytes());
//解密为原字符串
return aes.decryptStrFromBase64(encryptHex);
}
public int difference(Date nowDate, String decrypted){
return Math.abs((int)(nowDate.getTime()-Long.valueOf(decrypted))/1000);
}