Browse Source

开发接口api加解密框架

xudm 2 months ago
parent
commit
7c586f8c4b

+ 4 - 0
pom.xml

@@ -238,6 +238,10 @@
             <artifactId>lombok</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 2
src/main/java/com/xs/core/common/annotation/EntryIgnore.java

@@ -6,9 +6,9 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * 忽略接口响应
+ * 忽略接口基础加解
  */
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 public @interface EntryIgnore {
 }

+ 14 - 0
src/main/java/com/xs/core/common/annotation/OpenApiEntry.java

@@ -0,0 +1,14 @@
+package com.xs.core.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 开放接口基础加解密
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenApiEntry {
+}

+ 2 - 8
src/main/java/com/xs/core/config/satoken/SaTokenConfigure.java

@@ -2,14 +2,8 @@ package com.xs.core.config.satoken;
 
 import cn.dev33.satoken.interceptor.SaInterceptor;
 import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
-import cn.dev33.satoken.stp.SaTokenInfo;
 import cn.dev33.satoken.stp.StpLogic;
 import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson2.JSON;
-import com.xs.core.common.constant.ConstantConfig;
-import com.xs.core.common.content.UserContext;
-import com.xs.core.common.content.UserContextHolder;
 import com.xs.core.config.i18n.CustomLocaleChangeInterceptor;
 import com.xs.core.filter.UserContextInterceptor;
 import lombok.extern.slf4j.Slf4j;
@@ -32,10 +26,10 @@ public class SaTokenConfigure implements WebMvcConfigurer {
         // 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
         registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
                 .addPathPatterns("/**")
-                .excludePathPatterns("/login/coinLogin").order(-100);
+                .excludePathPatterns("/login/coinLogin", "/openapi/v1/*").order(-100);
         registry.addInterceptor(new UserContextInterceptor())
                 .addPathPatterns("/**")
-                .excludePathPatterns("/login/coinLogin")
+                .excludePathPatterns("/login/coinLogin", "/openapi/v1/*")
                 .order(-99);
         // 注册国际化拦截器
         registry.addInterceptor(new CustomLocaleChangeInterceptor())

+ 25 - 0
src/main/java/com/xs/core/controller/openapi/OpenApiController.java

@@ -0,0 +1,25 @@
+package com.xs.core.controller.openapi;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.xs.core.common.annotation.EntryIgnore;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/openapi/v1")
+@Slf4j
+@Tag(description = "开放接口", name = "开放接口")
+@EntryIgnore
+public class OpenApiController {
+    @PostMapping("/test")
+    public JSONObject test(@RequestBody JSONObject jsonObject) {
+        String jsonString = JSON.toJSONString(jsonObject);
+        log.info("jsonString:{}", jsonString);
+        return jsonObject;
+    }
+}

+ 123 - 0
src/main/java/com/xs/core/filter/OpenApiRequestHandler.java

@@ -0,0 +1,123 @@
+package com.xs.core.filter;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.xs.core.common.constant.ConstantConfig;
+import com.xs.core.common.exception.BusinessException;
+import com.xs.core.model.ResponseResult;
+import com.xs.core.request.BodyRequestWrapper;
+import com.xs.core.request.RequestWrapper;
+import com.xs.core.utils.OpenApiEncryptionUtils;
+import com.xs.core.utils.SecurityUtil;
+import com.xs.core.utils.redis.RedissonLockUtil;
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 开放接口请求处理器 用于解密请求参数
+ */
+@Slf4j
+@Component
+@Order(2)
+public class OpenApiRequestHandler implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        // 开放接口请求
+        String path = request.getServletPath();
+        if (!path.startsWith("/openapi/v1/")) {
+            chain.doFilter(request, response);
+            return;
+        }
+        log.info("开放接口请求过滤");
+        if (StringUtils.isNotBlank(request.getContentType()) && request.getContentType().contains("application/json")) {
+            RequestWrapper requestWrapper = new RequestWrapper(request);
+            // 拿到加密串
+            String data = requestWrapper.getBody();
+            data = data.replaceAll("\\s", "");
+            if (StringUtils.isBlank(data)) {
+                chain.doFilter(requestWrapper, response);
+                return;
+            }
+            JSONObject json = JSONObject.parseObject(data);
+            //验签
+            String encryptData = json.getString("encryptData");
+            if (!SecurityUtil.verifySign(encryptData, json.getString("identifying"))) {
+                byte[] results = _getErrorBytes(ResponseResult.failed("response.error.sign", null));
+                log.error("加密解析===》签名有误!");
+                servletResponse.setContentType("application/json; charset=UTF-8");
+                servletResponse.getOutputStream().write(results);
+                return;
+            }
+            // 解密
+            String result = OpenApiEncryptionUtils.aesDecrypt(encryptData);
+            // 请求有效性校验
+            JSONObject requestJson = JSONObject.parseObject(result);
+            if (!requestJson.containsKey("basicData")) {
+                byte[] results = _getErrorBytes(ResponseResult.failed("response.formatting.error", null));
+                log.error("加密解析===》请求参数有误!");
+                servletResponse.setContentType("application/json; charset=UTF-8");
+                servletResponse.getOutputStream().write(results);
+                return;
+            }
+            JSONObject basicJson = requestJson.getJSONObject("basicData");
+            if (!basicJson.containsKey("timeStamp") || !basicJson.containsKey("messageId")) {
+                byte[] results = _getErrorBytes(ResponseResult.failed("response.formatting.error", null));
+                log.error("加密解析===》请求参数有误!");
+                servletResponse.setContentType("application/json; charset=UTF-8");
+                servletResponse.getOutputStream().write(results);
+                return;
+            }
+            // 比对时间
+            if (System.currentTimeMillis() - basicJson.getLong("timeStamp") > 300000) {
+                log.error("加密解析===》更新当前设备时间为UTC标准时间!");
+                byte[] results = _getErrorBytes(ResponseResult.failed("response.error.timeout", null));
+                servletResponse.setContentType("application/json; charset=UTF-8");
+                servletResponse.getOutputStream().write(results);
+                return;
+            }
+            // 验证请求唯一性
+            String key = String.format("%s%s", ConstantConfig.MESSAGE_ID_PREFIX, basicJson.getString("messageId"));
+            try {
+                boolean tryLock = RedissonLockUtil.tryLock(key);
+                if (!tryLock) {
+                    byte[] results = _getErrorBytes(ResponseResult.failed("response.error.repeat", null));
+                    servletResponse.setContentType("application/json; charset=UTF-8");
+                    servletResponse.getOutputStream().write(results);
+                    return;
+                }
+            } catch (InterruptedException e) {
+                throw new BusinessException("验证请求唯一性发生异常");
+            }
+            if (!requestJson.containsKey("bizData") ||
+                    StringUtils.isBlank(requestJson.getString("bizData"))) {
+                request = new BodyRequestWrapper(request, "[]");
+            } else {
+                request = new BodyRequestWrapper(request, requestJson.getString("bizData"));
+            }
+            chain.doFilter(request, response);
+        } else {
+            chain.doFilter(request, response);
+        }
+    }
+
+    private byte[] _getErrorBytes(ResponseResult<?> responseResult) {
+        String result = OpenApiEncryptionUtils.aesEncrypt(JSON.toJSONString(responseResult));
+        String sign = SecurityUtil.getSign(result);
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("encryptData", result);
+        jsonObject.put("identifying", sign);
+        return jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);
+
+    }
+}

+ 75 - 0
src/main/java/com/xs/core/filter/OpenApiResponseHandler.java

@@ -0,0 +1,75 @@
+package com.xs.core.filter;
+
+import cn.hutool.core.util.ReflectUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONWriter;
+import com.alibaba.fastjson2.filter.ContextValueFilter;
+import com.xs.core.common.annotation.EntryIgnore;
+import com.xs.core.utils.OpenApiEncryptionUtils;
+import com.xs.core.utils.SecurityUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+
+/**
+ * openapi响应加解密拦截器
+ */
+@Component
+@ControllerAdvice
+@Order(value = 22)
+public class OpenApiResponseHandler implements ResponseBodyAdvice<Object> {
+
+    /**
+     * 返回true,才会走beforeBodyWrite方法
+     */
+    @Override
+    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
+        Method method = methodParameter.getMethod();
+        //如果方法上或者是类上有注解,才走beforeBodyWrite方法
+        return method != null && (method.isAnnotationPresent(EntryIgnore.class) || method.getDeclaringClass().isAnnotationPresent(EntryIgnore.class));
+    }
+
+    /**
+     * 响应加密
+     */
+    @Override
+    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse serverHttpResponse) {
+        // 拿到响应的数据
+        String json = JSON.toJSONString(body, (ContextValueFilter) (context, object, name, value) -> {
+                    Field field = ReflectUtil.getField(object.getClass(), name);
+                    //处理日期类型为空时返回空字符串
+                    if (null != field && value == null && LocalDateTime.class.isAssignableFrom(field.getType())) {
+                        return "";
+                    }
+                    return value;
+                },
+                JSONWriter.Feature.PrettyFormat,
+                JSONWriter.Feature.WriteNullStringAsEmpty,
+                JSONWriter.Feature.WriteNullListAsEmpty,
+                JSONWriter.Feature.WriteMapNullValue,
+                JSONWriter.Feature.WriteNulls);
+        // 进行加密
+        String result = OpenApiEncryptionUtils.aesEncrypt(json);
+        String sign = SecurityUtil.getSign(result);
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("encryptData", result);
+        jsonObject.put("identifying", sign);
+        return jsonObject;
+    }
+}

+ 12 - 2
src/main/java/com/xs/core/filter/RequestHandler.java

@@ -18,6 +18,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.owasp.esapi.ESAPI;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -35,6 +36,7 @@ import static java.util.regex.Pattern.*;
  */
 @Slf4j
 @Component
+@Order(1)
 public class RequestHandler implements Filter {
 
     @Value("${encryption.isEncryption}")
@@ -62,6 +64,14 @@ public class RequestHandler implements Filter {
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
         HttpServletRequest request = (HttpServletRequest) servletRequest;
         HttpServletResponse response = (HttpServletResponse) servletResponse;
+        // 开放接口请求过滤
+        String path = request.getServletPath();
+        log.info("加密解析===》" + path);
+        if (path.startsWith("/openapi/v1/")) {
+            chain.doFilter(request, response);
+            return;
+        }
+        log.info("加密解析过滤");
         byte[] results = _getErrorBytes();
         // 头攻击检测  过滤主机名(非白名单中的直接返回 403)
         String serverName = request.getServerName();
@@ -220,14 +230,14 @@ public class RequestHandler implements Filter {
 
     private byte[] _getErrorBytes() {
         if (isEncryption) {
-            String result = SecurityUtil.encryptSM2(responsePublicKey, JSON.toJSONString(ResponseResult.failed("response.error.encrypt")));
+            String result = SecurityUtil.encryptSM2(responsePublicKey, JSON.toJSONString(ResponseResult.failed("response.error.encrypt", null)));
             String sign = SecurityUtil.getSign(result);
             JSONObject jsonObject = new JSONObject();
             jsonObject.put("encryptData", result);
             jsonObject.put("identifying", sign);
             return jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8);
         } else {
-            return JSON.toJSONString(ResponseResult.failed("response.error.encrypt")).getBytes(StandardCharsets.UTF_8);
+            return JSON.toJSONString(ResponseResult.failed("response.error.encrypt", null)).getBytes(StandardCharsets.UTF_8);
         }
     }
 

+ 2 - 3
src/main/java/com/xs/core/filter/ResponseHandler.java

@@ -46,8 +46,8 @@ public class ResponseHandler implements ResponseBodyAdvice<Object> {
     @Override
     public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
         Method method = methodParameter.getMethod();
-        //如过方法上有注解,直接返回false,不走beforeBodyWrite方法
-        if (method != null && method.isAnnotationPresent(EntryIgnore.class)) {
+        //如果方法上或者是类上有注解,直接返回false,不走beforeBodyWrite方法
+        if (method != null && (method.isAnnotationPresent(EntryIgnore.class) || method.getDeclaringClass().isAnnotationPresent(EntryIgnore.class))) {
             return false;
         }
         return isEncryption;
@@ -64,7 +64,6 @@ public class ResponseHandler implements ResponseBodyAdvice<Object> {
             if (StringUtils.isNotBlank(httpRequest.getHeader("Knife4j-Gateway-Code"))) {
                 return body;
             }
-//            JSON.configWriterDateFormat(DatePattern.NORM_DATETIME_PATTERN);
             // 拿到响应的数据
             String json = JSON.toJSONString(body, (ContextValueFilter) (context, object, name, value) -> {
                         Field field = ReflectUtil.getField(object.getClass(), name);

+ 0 - 23
src/main/java/com/xs/core/init/MessageSourceInitializer.java

@@ -1,23 +0,0 @@
-//package com.xs.core.init;
-//
-//import com.xs.core.common.validation.CheckUtils;
-//import com.xs.core.model.ResponseResult;
-//import lombok.AllArgsConstructor;
-//import lombok.extern.slf4j.Slf4j;
-//import org.springframework.boot.CommandLineRunner;
-//import org.springframework.context.MessageSource;
-//import org.springframework.stereotype.Component;
-//
-//@Component
-//@AllArgsConstructor
-//@Slf4j
-//public class MessageSourceInitializer implements CommandLineRunner {
-//    private final MessageSource messageSource;
-//
-//    @Override
-//    public void run(String... args) throws Exception {
-//        ResponseResult.setMessageSource(messageSource);
-//        CheckUtils.setMessageSource(messageSource);
-//        log.info("MessageSource initialized successfully.");
-//    }
-//}

+ 15 - 4
src/main/java/com/xs/core/init/DatabaseInitializer.java → src/main/java/com/xs/core/init/ProjectInitializer.java

@@ -2,8 +2,11 @@ package com.xs.core.init;
 
 import com.xs.core.common.validation.CheckUtils;
 import com.xs.core.model.ResponseResult;
+import com.xs.core.utils.OpenApiEncryptionUtils;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.context.MessageSource;
 import org.springframework.stereotype.Component;
@@ -12,17 +15,25 @@ import javax.sql.DataSource;
 import java.sql.Connection;
 
 @Component
-@AllArgsConstructor
 @Slf4j
-public class DatabaseInitializer implements CommandLineRunner {
-    private final DataSource dataSource;
-    private final MessageSource messageSource;
+public class ProjectInitializer implements CommandLineRunner {
+    @Value("${openapi.aes-key}")
+    private String aesKey;
+    @Value("${openapi.aes-iv}")
+    private String aesIv;
+
+    @Autowired
+    private DataSource dataSource;
+    @Autowired
+    private MessageSource messageSource;
 
     @Override
     public void run(String... args) throws Exception {
         ResponseResult.setMessageSource(messageSource);
         CheckUtils.setMessageSource(messageSource);
         log.info("MessageSource initialized successfully.");
+        OpenApiEncryptionUtils.initAes(aesKey, aesIv);
+        log.info("Aes initialized successfully.");
         try (Connection connection = dataSource.getConnection()) {
             // 执行一个简单的查询来初始化连接
             connection.createStatement().execute("SELECT 1 from dual");

+ 163 - 0
src/main/java/com/xs/core/utils/OpenApiEncryptionUtils.java

@@ -0,0 +1,163 @@
+package com.xs.core.utils;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import cn.hutool.crypto.symmetric.AES;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class OpenApiEncryptionUtils {
+
+    private static RSA requestRsa;
+    private static RSA responseRsa;
+    private static AES aes;
+
+    /**
+     * 初始化rsa
+     */
+    public static void initRsa(String requestPrivateKey, String requestPublicKey, String responsePrivateKey, String responsePublicKey) {
+        requestRsa = new RSA(HexUtil.decodeHex(requestPrivateKey), HexUtil.decodeHex(requestPublicKey));
+        responseRsa = new RSA(HexUtil.decodeHex(responsePrivateKey), HexUtil.decodeHex(responsePublicKey));
+    }
+
+    public static void initAes(String privateKey, String iv) {
+        aes = new AES("CBC", "PKCS7Padding",
+                // 密钥,可以自定义
+                privateKey.getBytes(),
+                // iv加盐,按照实际需求添加
+                iv.getBytes());
+    }
+
+
+    private OpenApiEncryptionUtils() {
+    }
+
+    /**
+     * 生成秘钥对
+     *
+     * @return 公钥和私钥
+     */
+    public static Map<String, String> generatorRsaKey() {
+        RSA rsa = new RSA();
+        //获得私钥
+        String privateKeyBase64 = rsa.getPrivateKeyBase64();
+        //获得公钥
+        String publicKeyBase64 = rsa.getPublicKeyBase64();
+        return new HashMap<>(2) {{
+            put("publicKey", HexUtil.encodeHexStr(publicKeyBase64));
+            put("privateKey", HexUtil.encodeHexStr(privateKeyBase64));
+        }};
+    }
+
+    /**
+     * 响应加密 使用私钥加密 使用公钥解密
+     *
+     * @param data 数据
+     * @return 加密后的数据
+     */
+    public static String rsaEncryptRespDataByPrivateKey(String data) {
+        return responseRsa.encryptHex(StrUtil.bytes(data), KeyType.PrivateKey);
+    }
+
+    /**
+     * 响应解密 使用私钥加密 使用公钥解密
+     *
+     * @param data 数据
+     * @return 解密后的数据
+     */
+    public static String rsaDecryptRespDataByPublicKey(String data) {
+        return responseRsa.decryptStr(data, KeyType.PublicKey);
+    }
+
+    /**
+     * 请求解密 使用公钥加密 使用私钥解密
+     *
+     * @param data 数据
+     * @return 解密后的数据
+     */
+    public static String rsaDecryptReqDataByPrivateKey(String data) {
+        return requestRsa.decryptStr(data, KeyType.PrivateKey);
+    }
+
+    /**
+     * 请求加密 使用公钥加密 使用私钥解密
+     *
+     * @param data 数据
+     * @return 加密后的数据
+     */
+    public static String rsaEncryptReqDataByPublicKey(String data) {
+        return requestRsa.encryptHex(StrUtil.bytes(data), KeyType.PublicKey);
+    }
+
+    /**
+     * aes加密
+     *
+     * @param data 数据
+     * @return 加密后的数据
+     */
+    public static String aesEncrypt(String data) {
+        return aes.encryptHex(data);
+    }
+
+    /**
+     * aes解密
+     *
+     * @param data 数据
+     * @return 解密后的数据
+     */
+    public static String aesDecrypt(String data) {
+        return aes.decryptStr(data);
+    }
+
+
+    public static void main(String[] args) {
+        //
+//        Map<String, String> stringStringMap = generatorRsaKey();
+//        String jsonString = JSON.toJSONString(stringStringMap);
+//        System.out.println(jsonString);
+//        {
+//    "privateKey": "4d494943647749424144414e42676b71686b6947397730424151454641415343416d457767674a6441674541416f47424150733672785139444763515a656b32464174446c5835584679357261323338396b46636a4a586d79774a7a4170474f334431305541625754526969745544593275646135625a516578426c2f4f7a316533746d782f3538424c66684d576f537855645462314e63784751533049486e412f4b554943516e6f78716834384e45336e515a49506130616f56726162443455654d787a644b3375497a73536a776538442b63705a4c776f67734c41674d42414145436759416e67486f43365535796d4e444e586551586d5641714d4c444477476d416b38353352797752474962736546543775687477646b4958426e5238336e3369776d446a7538456577697a4d7a7078356f784a565a755850457352554756717a54703158564643682b394e6a65763178746b59343930737a62445a4b3258312b4e61616d754c53586b6f62677a57555a79675369796b413966777069646d5634437175664d7176423938716734514a424150376f5454626c7a574e58306f6a6245316f796e303431754d305334346b44722f705a4e304258696745384f43526f6a564b693671684c343549576963524c54686271382b556d49384d555a635a685a767a3836576b4351514438546c69726a502f5053782f61585275444c45626a42644e4c51393858646c6e3967353068543738584b4f516b7177584962394e645641762b4a5374515149362f7466346165487750486c575a484b652f64613554416b45417071783263494c715052376268716a59696f32334a49683041594e73533961685a6d7958642f6246516647434e437734322b4f7930384272574d5a72356e486d3659315056484950794371364d584457796d30456f514a42414d4456664732354f54614d32303641784f74505a7570535a486873366c4137553349774b6d4c7757554e784c4656654a50425a6a336b514b493559694338772b436c4d426d62693253615137366b7a506e355669694d4351455a7134525350447a2b50674c4a344b506e336272475562586e434962674d31662f6d6f4a4256576f6c75552f454a6d4c59575a6e6d74526a634d32524667587954786e46787737306e4879527a734b5379356d76633d",
+//    "publicKey": "4d4947664d413047435371475349623344514542415155414134474e4144434269514b42675144374f7138555051786e454758704e68514c5135562b56786375613274742f505a42584979563573734363774b526a74773964464147316b30596f725641324e726e57755732554873515a667a73395874375a73662b66415333345446714573564855323954584d526b45744342357750796c43416b4a364d616f655044524e3530475344327447714661326d772b46486a4d6333537437694d37456f384876412f6e4b5753384b494c4377494441514142"
+//}
+//        String PrivateKey = "4d494943647749424144414e42676b71686b6947397730424151454641415343416d457767674a6441674541416f47424150733672785139444763515a656b32464174446c5835584679357261323338396b46636a4a586d79774a7a4170474f334431305541625754526969745544593275646135625a516578426c2f4f7a316533746d782f3538424c66684d576f537855645462314e63784751533049486e412f4b554943516e6f78716834384e45336e515a49506130616f56726162443455654d787a644b3375497a73536a776538442b63705a4c776f67734c41674d42414145436759416e67486f43365535796d4e444e586551586d5641714d4c444477476d416b38353352797752474962736546543775687477646b4958426e5238336e3369776d446a7538456577697a4d7a7078356f784a565a755850457352554756717a54703158564643682b394e6a65763178746b59343930737a62445a4b3258312b4e61616d754c53586b6f62677a57555a79675369796b413966777069646d5634437175664d7176423938716734514a424150376f5454626c7a574e58306f6a6245316f796e303431754d305334346b44722f705a4e304258696745384f43526f6a564b693671684c343549576963524c54686271382b556d49384d555a635a685a767a3836576b4351514438546c69726a502f5053782f61585275444c45626a42644e4c51393858646c6e3967353068543738584b4f516b7177584962394e645641762b4a5374515149362f7466346165487750486c575a484b652f64613554416b45417071783263494c715052376268716a59696f32334a49683041594e73533961685a6d7958642f6246516647434e437734322b4f7930384272574d5a72356e486d3659315056484950794371364d584457796d30456f514a42414d4456664732354f54614d32303641784f74505a7570535a486873366c4137553349774b6d4c7757554e784c4656654a50425a6a336b514b493559694338772b436c4d426d62693253615137366b7a506e355669694d4351455a7134525350447a2b50674c4a344b506e336272475562586e434962674d31662f6d6f4a4256576f6c75552f454a6d4c59575a6e6d74526a634d32524667587954786e46787737306e4879527a734b5379356d76633d";
+//        String PublicKey = "4d4947664d413047435371475349623344514542415155414134474e4144434269514b42675144374f7138555051786e454758704e68514c5135562b56786375613274742f505a42584979563573734363774b526a74773964464147316b30596f725641324e726e57755732554873515a667a73395874375a73662b66415333345446714573564855323954584d526b45744342357750796c43416b4a364d616f655044524e3530475344327447714661326d772b46486a4d6333537437694d37456f384876412f6e4b5753384b494c4377494441514142";
+//        RSA rsa = new RSA(HexUtil.decodeHexStr(PrivateKey), HexUtil.decodeHexStr(PublicKey));
+//        //私钥加密,公钥解密
+////        byte[] encrypt = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
+//        String s = rsa.encryptHex(StrUtil.bytes("我是一段测试aaaa"), KeyType.PrivateKey);
+//        System.out.println(s);
+//        String s1 = rsa.decryptStr(s, KeyType.PublicKey);
+//        System.out.println(s1);
+
+//        String reqPublicKey = "";
+//        String reqPrivateKey = "";
+//        String resPrivateKey = "";
+//        String resPublicKey = "";
+//        initRsa(reqPrivateKey, reqPublicKey, resPrivateKey, resPublicKey);
+//
+//        String s = encryptReqDataByPublicKey("测试数据哈哈哈哈133141414");
+//        System.out.println(s);
+//
+//        String s1 = decryptReqDataByPrivateKey(s);
+//        System.out.println(s1);
+
+        String content = "cacaca擦手巾插拔式吃吧擦擦吧阿是擦肩插拔式超级兵5757u8484u18123213112@^*&^%";
+        AES aes = new AES("CBC", "PKCS7Padding",
+                // 密钥,可以自定义
+                "GPVRl6EdFRy0nfFHKxGaEzogygwO1V4r".getBytes(),
+                // iv加盐,按照实际需求添加
+                "EDjszv7a7Vw6MtsN".getBytes());
+        // 加密为16进制表示
+//        String encryptHex = aes.encryptHex(content);
+//        System.out.println(encryptHex);
+        String encryptHex = "a7d2a41eb3637c54d91fbadd287d18907a46d84cd7694572f6e1ac84f980db949fd49eb8c1f975e279c1e845720f18521e8d5b9d914a83903757ab60b1c8d923e853cf4cdd3e83e7e171799ba1e48313423fac8bba682822d02b06643eeb0cc52daedb7df9d4aa8f215761be59aca92f36dc85ad2a49f781057d6b8faec0f5aed8e8698e41cfdaadbc264511a0e337933730ca5180c2d2361915650898f7ef46";
+        String decryptStr = aes.decryptStr(encryptHex);
+        System.out.println(decryptStr);
+
+    }
+}

+ 5 - 0
src/main/resources/application-dev.yml

@@ -157,3 +157,8 @@ xssFilter:
 interfaceLog:
   # 是否开启接口日志
   openInterfaceLog: false
+
+# openapi
+openapi:
+  aes-key: GPVRl6EdFRy0nfFHKxGaEzogygwO1V4r
+  aes-iv: EDjszv7a7Vw6MtsN