欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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);
    }
相关标签: 时间戳