springboot全面加密方案

springboot全面加密方案

  • 最近项目上又出幺蛾子了,甲方要求前端后台全部的数据都需要加密处理,不允许明文。简单的来说,就是传的参数是加密数据,然后接口返回给前端的数据也是加密数据。

  • 显示的效果就是比方说,前端传给我的是一个json

    {
    "data":"8cfd4ebd90359d687b0dd8345fad44ab3405cecd81e9d7e5da5ec994259e171575aa2384a024677276c98db9c13ef66e"
    }

  • 然后我拿到这个数据后解析成原本我的接口的参数,然后传到接口中处理逻辑,然后把返回值也加密,返回给前端的值类似于

    {
    "result":"6CC375B93947D06ED64E4A0E21227147C0D63EB71BD871EFFAF3A6319A7A6519B55E8919E0B505321230CC0DD951B535F6C8BB42EBFF6DA07B6F7C638658714F59D0522098BA91BB2B51174EF08B9DC99A98D99BD6A31599A995CAB8996EE4C2"
    }

  • 于是就要开始思考如何解决该问题,由于项目里没有统一的格式规范,各种类型层出不穷,比如@RequestBody,或者@RequestParam,各种表单提交或者json提交,然后返回值也是各种各样的。这对于我做全面加密产生了极大的阻碍。

  • 正常做首先看网上有没有现成的,但是经过我多次试验,均无法满足我的全部需求,它只能处理json格式的,对于我表单提交的方式那就是一个无能为力

  • 然后还有拦截器的方式,本来我是非常看好这个方法,但是拦截器HandlerInterceptor,我实在是无法实现解析后再把值变为表单提交进原来的接口中,如果有大佬实现了,希望能告诉在下,如何实现。

  • 同理自定义注解,也是同样的原因,我始终无法实现把解析后的参数转化为表单再重新提交进接口

  • 最后我使用过滤器的方式来实现,过滤器,缺失能实现把值转化为表单重新提交进接口

  • 而把返回值重新进行加密的方式,我选择使用implements ResponseBodyAdvice,我测试目前基本上返回值都会经过这里,重新进行加密封装后,再返回给前端


  • 进入filter后,重新赋值
    MyParameterRequestWrapper wrapRequest = new MyParameterRequestWrapper(request, newParams, jsonData);
    其中,newParams传的是表单的数据,jsonData传的是json的数据,都是解析出来的数据,然后继续进入下一个过滤
    filterChain.doFilter(wrapRequest, servletResponse);

    public class MyParameterRequestWrapper extends HttpServletRequestWrapper {
    private Map<String, String[]> params;
    private String requestBody = null;

    复制代码
      /**
       * Constructs a request object wrapping the given request.
       *
       * @param request the {@link HttpServletRequest} to be wrapped.
       * @throws IllegalArgumentException if the request is null
       */
      public MyParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> params, String requestBody) {
          super(request);
          this.params = params;
          this.requestBody = requestBody;
      }
    
      @Override
      public Map<String, String[]> getParameterMap() {
          return params;
      }
    
      @Override
      public Enumeration<String> getParameterNames() {
          Vector<String> l = new Vector<>(params.keySet());
          return l.elements();
      }
    
      @Override
      public String[] getParameterValues(String name) {
          Object v = params.get(name);
          if (v == null) {
              return null;
          } else if (v instanceof String[]) {
              return (String[]) v;
          } else if (v instanceof String) {
              return new String[]{(String) v};
          } else {
              return new String[]{v.toString()};
          }
      }
    
      @Override
      public String getParameter(String name) {
          Object v = params.get(name);
          if (v == null) {
              return null;
          } else if (v instanceof String[]) {
              String[] strArr = (String[]) v;
              if (strArr.length > 0) {
                  return strArr[0];
              } else {
                  return null;
              }
          } else if (v instanceof String) {
              return (String) v;
          } else {
              return v.toString();
          }
      }
    
      @Override
      public BufferedReader getReader() throws IOException {
          return new BufferedReader(new StringReader(requestBody));
      }
    
      @Override
      public ServletInputStream getInputStream() throws IOException {
    
          ServletRequest request = getRequest();
    
          return new ServletInputStream() {
    
              @Override
              public boolean isFinished() {
                  return false;
              }
    
              @Override
              public boolean isReady() {
                  return false;
              }
    
              @Override
              public void setReadListener(ReadListener readListener) {
    
              }
    
              private InputStream in = new ByteArrayInputStream(
                      requestBody.getBytes(request.getCharacterEncoding() == null ? "UTF-8" : request.getCharacterEncoding()));
    
              // 读取 requestBody 中的数据
              @Override
              public int read() throws IOException {
                  return in.read();
              }
          };
      }

    }

    /**

    • 响应加解密拦截器

    • @author lyk
      */
      @Component
      @ControllerAdvice
      public class ResponseHandler implements ResponseBodyAdvice<Object> {

      // 这里假设你希望只有某些特定的 Controller 或方法走这个处理器
      @Override
      public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
      //这里可以写一些条件return false,代表不进入返回加密流程
      return true;
      }

      /**

      • 响应加密
        */
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse serverHttpResponse) {
        //这里body就是返回值,对它进行加密即可
        String encrypt = encryptEcb(body);

        JSONObject json = new JSONObject();
        json.put("result", encrypt);
        return json;
        }
        }

相关推荐
他҈姓҈林҈2 小时前
使用 Spring Boot 进行开发
spring boot
柏油4 小时前
MySQL InnoDB 行锁
数据库·后端·mysql
咖啡调调。4 小时前
使用Django框架表单
后端·python·django
Java&Develop4 小时前
onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2
前端·spring boot·编辑器
白泽talk4 小时前
2个小时1w字| React & Golang 全栈微服务实战
前端·后端·微服务
摆烂工程师4 小时前
全网最详细的5分钟快速申请一个国际 “edu教育邮箱” 的保姆级教程!
前端·后端·程序员
一只叫煤球的猫5 小时前
你真的会用 return 吗?—— 11个值得借鉴的 return 写法
java·后端·代码规范
Asthenia04125 小时前
HTTP调用超时与重试问题分析
后端
颇有几分姿色5 小时前
Spring Boot 读取配置文件的几种方式
java·spring boot·后端
AntBlack5 小时前
别说了别说了 ,Trae 已经在不停优化迭代了
前端·人工智能·后端