Web前后端笔记-通过对称加密算法和信息摘要算法防止数据重放

368 篇文章 20 订阅
28 篇文章 2 订阅

理论图如下:

这里使用时间戳和随机数和正常提交的表单数据生成MD5摘要,再使用某16位密钥把MD5进行AES加密,生成128位的数据。然后提交给服务器。

 

服务器先看提交的时间戳是否在范围内(如2分钟),如果时间非法就直接返回。

然后看各个数据进行某种有规则的算法,生成MD5看看是否与提交的MD5一样,不一样说明是被串改的。

如果MD5一样,对比下数据库中目前时间范围内(如2分钟)是不是二次提交,如果是就拒绝。

将MD5和某16位密钥进行AES加密,如果和客户端传上来的一样,那么就可以回数据了。

 

 

这里本人贴下对应的后端代码:

前端请求如下:

后端代码如下:

@SuppressWarnings("ALL")
@Component
public class XInterceptor extends HandlerInterceptorAdapter {


    @Autowired
    AuthXXXXService authService;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {


        if(httpServletRequest.getMethod().equals("GET")){

            String url = httpServletRequest.getRequestURI();
            String contextPath = httpServletRequest.getServletPath();
            String para = httpServletRequest.getQueryString();
            Enumeration<String> parameterNames = httpServletRequest.getParameterNames();
            Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();

            //参数是否正常
            if(!parameterMap.containsKey("timestamp") || !parameterMap.containsKey("signature") || !parameterMap.containsKey("shield")){

                httpServletResponse.sendError(VoXXXXEm.PARA_ERROR.getCode());
                return false;
            }

            //先检测签名是否过期 30s内不会过期
            Long timestamp = Long.valueOf(parameterMap.get("timestamp")[0]);
            Long currentStamp = System.currentTimeMillis();

            if(timestamp < (currentStamp - 30 * 1000)){

                httpServletResponse.sendError(VoEm.TIMEOUT.getCode());
                return false;
            }

            //检查签名是否合法
            String originStr = "";
            for(Enumeration key = parameterNames ; parameterNames.hasMoreElements();){

                String KeyPara = key.nextElement().toString();
                if(KeyPara.equals("signature") || KeyPara.equals("shield"))
                    continue;

                originStr += parameterMap.get(KeyPara)[0] + "$";
            }
            originStr = originStr.substring(0, originStr.length() - 1);
            String md5Str = MD5Utils.generateMD5(originStr);


            //验证签名
            if(!md5Str.equals(parameterMap.get("signature")[0])){

                httpServletResponse.sendError(VoXXXXEm.SIGN_ERROR.getCode());
                return false;
            }

            //禁止重放
            if(authService.isSignatureInResetMap(md5Str)){

                httpServletResponse.sendError(VoXXXXEm.REST_ERROR.getCode());
                return false;
            }


            //验证护盾
            String originShield = parameterMap.get("shield")[0];

            //key值为签名的前16位
            String decrypt = AESUtil.decrypt(originShield, parameterMap.get("signature")[0].substring(0, 16));

            if(!parameterMap.get("signature")[0].equals(decrypt)){

                httpServletResponse.sendError(VoXXXXEm.SHIELD_ERROR.getCode());
                return false;
            }

            //加入到禁止重放里面
            authService.addResetMap(md5Str, timestamp);

            //System.out.println("over");
        }
        else{

        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

这里提下

AuthXXXXService存储了MD5的相关数据。这里在Spring Boot中有个调度线程池

如下,每隔一段数据就清空下:

 

  • 43
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值