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 {

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

      /**

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

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

      相关推荐
      一 乐2 小时前
      家政服务管理系统|基于springboot + vue家政服务管理系统(源码+数据库+文档)
      java·数据库·vue.js·spring boot·论文·毕设·家政服务管理系统
      IT_陈寒2 小时前
      Vite热更新失效?可能你在用Windows
      前端·人工智能·后端
      椰椰椰耶3 小时前
      [SpringCloud][14]OpenFeign参数传递方法
      后端·spring·spring cloud
      onething3653 小时前
      Spring Boot + Spring AI 从入门到实战:7天转型计划 Day 3 —— 消息表设计 + 级联删除 + 事务管理
      人工智能·后端
      荣江4 小时前
      Hermes Agent 代码仓库打包工具使用指南(repomix-rs 高性能版)
      后端
      王某某人4 小时前
      LangChain4j 入门:Java 程序员的第一个 AI 对话程序
      人工智能·后端
      码农刚子4 小时前
      从零开始:在 Windows 服务器上部署 Node.js 项目(小白实战教程)
      后端·node.js
      Cache技术分享4 小时前
      435. Java 日期时间 API - Clock 灵活获取当前时间
      前端·后端
      浩子coding4 小时前
      通过 Spring AI Alibaba 源码,看如何玩转 ReAct 智能体范式
      人工智能·后端
      星浩AI4 小时前
      合规项目大模型如何部署?硬件选型 + vLLM/LMDeploy 实战
      pytorch·后端·llm