资讯详情

针对全局的接口出入参加解密-AES/ECB/PKCS5Padding

首先 - AES通过枚举类保存过枚举类保存密钥。

package com.ha.common.utils;  import com.ha.common.enums.EncryptEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.util.Base64Utils;  import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom;  /**  * @author pph  * @date 2022/7/8 9:54  * @desciption  */ @Slf4j public class AesUtils {          private static final Logger LOGGER = LoggerFactory.getLogger(AesUtils.class);      /**      * key 加密算法      */     private static final String KEY_ALGORITHM = "AES";      /**      * 固定值      */     private static final String SECRET_RANDOM = "SHA1PRNG";      /**      * 编码方式      */     public static final String ENCODING_TYPE = "UTF-8";      /**      * 默认加密算法      */     private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";      /**      * 私钥      */     private static final String ASSETS_DEV_PWD_FIELD = EncryptEnum.ENCRYPT_ENUM.getCode();      /**      * 加密      */     public static String encrypt(String content, String password) {          try {             // 创建密码器             Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);              byte[] byteContent = content.getBytes(ENCODING_TYPE);             // 密码器初始化为加密模式             cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));             // 加密             byte[] result = cipher.doFinal(byteContent);             // 通过Base64转码返回             return Base64Utils.encodeToString(result);         } catch (Exception e) {             LOGGER.info("aesencrypt000 error ", e);         }          return null;     }      /**      * AES 解密      */     public static String decrypt(String content, String password) {          try {             //实例化             Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);             //使用密钥初始化,设置为解密模式             cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));             SecretKeySpec secretKey = getSecretKey(password);             //执行操作             byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content)); //            Base64 base64 = new Base64(); //            byte[] result = base64.decodeBase64(password.getBytes());             return new String(result, "utf-8");         } catch (Exception e) {             LOGGER.info("aesdecrypt000 error ", e);         }          return null;     }      /**      * 生成加密密钥      */     private static SecretKeySpec getSecretKey(String password) {          ///返回生成指定算法的密钥生成器 KeyGenerator 对象         KeyGenerator kg;         try {             kg = KeyGenerator.getInstance(KEY_ALGORITHM);             SecureRandom secureRandom = SecureRandom.getInstance(SECRET_RANDOM);             secureRandom.setSeed(password.getBytes());             //AES 要求密钥长度为 128             kg.init(128, secureRandom);             //生成密钥             SecretKey secretKey = kg.generateKey();             // 转换为AES专用密钥             return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);         } catch (NoSuchAlgorithmException e) {             LOGGER.info("aesgetSecretKey000 error ", e);         }          return null;     }        public static void main(String[] args) {          String str="MK9wOrPiGGT1eCc5ovV9ggZPBD7HjsrW6HOOnD0mMd5sTF/IupPGJBelRKgpPPZGxdbap2VGqLu44OU4tv0EmnRUdP8mkLyO7Rodw88qEFav8jyP8TnVxpRrjWOZCo 6";         System.out.println(AesUtils.decrypt(str, EncryptEnum.ENCRYPT_ENUM.getCode()));          System.out.println("---------------------------");         String str1="BwZiUICxJIZ4Ua7VrdZTVEubw/UCNB/sxcS6iqswaT3lU942bfjbZyIdlO3IWkEWhxoG9vqBwZjL ysL83gtiK ZHEf/wJl8orRi0Ty3IsWmC7voZch2bOsVzQRQqGSHCq99iiBysmeGZh5PxrIspYy O6AN/nTvi9t3Mj3JfK9vKcv fq6ypqt5XyUaXQkcOR4rUELM9YtU78c9zkS994Z0EgwInGZJXKZxsb3qEiu6jAu2FUWYs8OtjM3XjfaZV3bVuvTNMbjJIRSkbvpi8m2hvmLjBYBj163ptqPuNxYX9Kyw2aK4nHO9ictlz0BDWjtVaKi0923HVKUvDFN5JtPXd1FPrg7N7 L56 jKsPfBVX4wjmCrj1RK/oZEjUDNwzXfAnYQA9dMSur8Clkcc0fN0qjBScu7DUBkWainnhC0U0jHCp04/lPMTlXgmhaOnXEakozP3g8M0KvO3CSRwWUGU119ZIEbUPZtaSv6SiNbLDn7jLM4n1cS3XgS663J1zr8CmC7cBeaJL6GnpLaEvqhaafwidTcdueM5KABji/VhX4N9EfZd0G7T2qMkitmDLNCw9BMsIi1tBnbsZU2 rln7baowVZnRyG6SDGHDiFKDlyvWU4MUJPqxI6xm8rnsPYTdIW5KOo//1OQqqMTy/yRz33IJQa8tWBGbGEr2Hs91ItH4DlLlowI0RIAHhYwpqN1EsYhU lkyeba7uuz8hdkPXenJnW70xuYT2sFqYWVBeFCXV0aqxzpvqVAiGiJdEo5gnKUNVCaKlsXbOEKjfSpLYzMUwcRw8b9V8VdsPlkxBc3talx86eJvdOlGo0HrTuKfxv6nS0rSR9xH50VTPx2IvcPTEYMe9398nkdbQoH5gA7pfOHB39m6W6WLS1SGLhA8A8ucvh iRvmiSGWW6lTptsQW0AVlGbQaqZMF5sBHZV0Of6HUB9JFZylJTE71oD4J9JZZdphmKozJuLtWtYiNb/H80TBDUoph1n3HTU=";         System.out.println(AesUtils.decrypt(str1, EncryptEnum.ENCRYPT_ENUM.getCode()));     }  } 

枚举类 - 设置密钥

package com.ha.common.enums;  /**  * @author pph  * 加密密钥枚举
 */
public enum EncryptEnum
{
    ENCRYPT_ENUM("666666abcdefg");

    private final String code;

    EncryptEnum(String code)
    {
        this.code = code;
    }

    public String getCode()
    {
        return code;
    }

}

本文的方法是通过过滤器进行接口出入参的加解密,这是过滤器的代码部分

2、新建过滤器

这个过滤器没有指定了url进入规则,暂时所有的url都能进入到此过滤器中。在doFilter方法中使用了自定义的ResponseWrapper对response进行封装。Controller接口走完之后获取到接口返回的数据并再次封装到response。

package com.ha.common.filter;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.ha.common.enums.EncryptEnum;
import com.ha.common.utils.AesUtils;

/**
 * Repeatable 过滤器
 */
public class RepeatableFilter implements Filter
{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException
    {
//        chain.doFilter(request, response);
        if(((HttpServletRequest) request).getMethod().equals("GET") || ((HttpServletRequest) request).getMethod().equals("POST")||
           ((HttpServletRequest) request).getMethod().equals("PUT") || ((HttpServletRequest) request).getMethod().equals("DELETE"))
        {
            String requestURI = ((HttpServletRequest) request).getRequestURI();
            //用户登录是否加密解密
//            if (requestURI.equals("/busi/user/app/loginByPwd")){
//                chain.doFilter(request, response);
//                return;
//            }
            //上传文件不许加解密
            if (requestURI.equals("/system/user/profile/avatar")){
                chain.doFilter(request, response);
                return;
            }

        AesRequestWrapper aesrequestWrapper = null;
        AesResponseWrapper aesResponseWrapper = null;

        aesrequestWrapper = new AesRequestWrapper((HttpServletRequest) request);
        aesResponseWrapper = new AesResponseWrapper((HttpServletResponse) response);
        chain.doFilter(aesrequestWrapper, (ServletResponse) aesResponseWrapper);
        // 获取response返回的内容并重新写入response, 若获取到的数据是乱码,可设置response的编码为系统默认编码集
        String result = aesResponseWrapper.getResponseData(response.getCharacterEncoding());

        //加密
        String encryptResponse = AesUtils.encrypt(result, EncryptEnum.ENCRYPT_ENUM.getCode());

        Object object = JSONObject.parse(result);
        response.getOutputStream().write(encryptResponse.getBytes());
        response.getOutputStream().flush();
        response.getOutputStream().close();
        }
    }
    
    @Override
    public void destroy()
    {

    }

    /**
     * 路径不处理
     * @param request
     * @param strArr
     * @return
     */
    public boolean isIgnore(HttpServletRequest request,String[] strArr) {
        String path=request.getRequestURI();
        for(String ignore:strArr) {
            if(path.contains(ignore)) {
                return true;
            }
        }
        return false;
    }

}

之后就是关于对request请求中body的修改及response的加密。博主这边封装了两个类去解决的。

AesResponseWrapper获取接口的返回值并执行加密
package com.ha.common.filter;

import com.alibaba.fastjson.JSONObject;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

public class AesResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream buffer = null;

    private ServletOutputStream out = null;

    private PrintWriter writer = null;

    public AesResponseWrapper(HttpServletResponse response) throws IOException {
        super(response);
        buffer = new ByteArrayOutputStream();
        out = new WapperedOutputStream(buffer);
        writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
        if (writer != null) {
            writer.flush();
        }
    }

    @Override
    public void reset() {
        buffer.reset();
    }

    /**
     * @Description: 获取response中数据的方法
     **/
    public String getResponseData(String charset) throws IOException {
        flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
        System.out.println(buffer.toString());
        byte[] bytes = buffer.toByteArray();
        System.out.println(buffer);
        JSONObject parse = (JSONObject) JSONObject.parse(buffer.toString());
        System.out.println(parse);
        //            return new String(bytes, "UTF-8");
        return String.valueOf(buffer);

    }

    //内部类,对ServletOutputStream进行包装,指定输出流的输出端
    private class WapperedOutputStream extends ServletOutputStream {

        private ByteArrayOutputStream bos = null;

        public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
            bos = stream;
        }

        //将指定字节写入输出流bos
        @Override
        public void write(int b) throws IOException {
            bos.write(b);
        }

        @Override
        public boolean isReady() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void setWriteListener(WriteListener listener) {
            // TODO Auto-generated method stub

        }
    }

}

AesRequestWrapper获取请求的Body并修改重新带到接口
package com.ha.common.filter;

import com.alibaba.fastjson.JSONObject;
import com.ha.common.enums.EncryptEnum;
import com.ha.common.utils.AesUtils;
import com.ha.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

/**
 * @author pph
 */
public class AesRequestWrapper extends HttpServletRequestWrapper {

    private static final Logger logger = LoggerFactory.getLogger(AesRequestWrapper.class);

    /**
     * 存储请求数据
     */
    private String body;

    public AesRequestWrapper(HttpServletRequest request) {
        super(request);
        renewBody(request);
    }

    /**
     * 重写getInputStream方法
     */
    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() {
                return byteArrayInputStream.read();
            }
        };
    }

    /**
     * 重写getReader方法
     */
    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    /**
     * 读取body的值
     */
    private void renewBody(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
                if(!StringUtils.isEmpty(stringBuilder)){
                    String str = stringBuilder.toString();
                    JSONObject parse = (JSONObject) JSONObject.parse(str);
                    String data = parse.getString("data");
                    //data加密代码为空  不解密
                    if (StringUtils.isEmpty(parse.getString("data"))){
                        body = str;
                        return;
                    }
                    body = AesUtils.decrypt(data, EncryptEnum.ENCRYPT_ENUM.getCode());
                    System.out.println(body);
                }
            }
        } catch (Exception ex) {
            logger.error("报错请求接口的路径:{}",request.getRequestURI());
            logger.error("请求入参aes解密失败:{}",ex);
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    logger.error("请求入参base64转换失败:{}",ex);
                }
            }
        }
    }

    public String getBody() {
        return body;
    }

}

标签: ad7819yrz集成电路ic

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台