From 10b5b0e82a2125ee90ff036aed877d2e6cadfe51 Mon Sep 17 00:00:00 2001
From: wdhcr <w18700852607@163.com>
Date: 星期一, 10 七月 2023 16:06:49 +0800
Subject: [PATCH] 配合前端使用jsencrypt实现接口参数加密功能, 可在application.yml中全局开启, 也可通过自定义注解@ApiDecrypt对单独接口开启.

---
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java                             |   34 +++
 ruoyi-admin/pom.xml                                                                                                                    |    6 
 ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    1 
 ruoyi-common/ruoyi-common-bom/pom.xml                                                                                                  |    7 
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java                                         |   54 ++++++
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java                                   |   55 ++++++
 ruoyi-admin/src/main/resources/application.yml                                                                                         |   10 +
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java                                       |   15 +
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java                            |  103 +++++++++++
 ruoyi-common/pom.xml                                                                                                                   |    1 
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java                                     |   47 +++++
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java                                           |   52 +++++
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java                                            |   13 +
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java                                           |   57 ++++++
 ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java                                         |   35 +++
 ruoyi-common/ruoyi-common-cryptapi/pom.xml                                                                                             |   34 +++
 16 files changed, 524 insertions(+), 0 deletions(-)

diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 39731b1..3d121c0 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -87,6 +87,12 @@
             <artifactId>JustAuth</artifactId>
         </dependency>
 
+        <!-- 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡 -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-cryptapi</artifactId>
+        </dependency>
+
 
         <!-- skywalking 鏁村悎 logback -->
 <!--        <dependency>-->
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index fcc1865..878a9c3 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -173,6 +173,16 @@
   publicKey:
   privateKey:
 
+# api鎺ュ彛鍔犲瘑
+api-decrypt:
+  # 鏄惁寮�鍚叏灞�鎺ュ彛鍔犲瘑
+  enable: false
+  # AES 鍔犲瘑澶存爣璇�
+  headerFlag: AES
+  # 鍏閽� 闈炲绉扮畻娉曠殑鍏閽� 濡傦細SM2锛孯SA
+  publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
+  privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
+
 springdoc:
   api-docs:
     # 鏄惁寮�鍚帴鍙f枃妗�
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 45493d3..e77ea23 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -33,6 +33,7 @@
         <module>ruoyi-common-encrypt</module>
         <module>ruoyi-common-tenant</module>
         <module>ruoyi-common-websocket</module>
+        <module>ruoyi-common-cryptapi</module>
     </modules>
 
     <artifactId>ruoyi-common</artifactId>
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index 93d1189..5014954 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -171,6 +171,13 @@
                 <artifactId>ruoyi-common-websocket</artifactId>
                 <version>${revision}</version>
             </dependency>
+
+            <!-- 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡 -->
+            <dependency>
+                <groupId>org.dromara</groupId>
+                <artifactId>ruoyi-common-cryptapi</artifactId>
+                <version>${revision}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/ruoyi-common/ruoyi-common-cryptapi/pom.xml b/ruoyi-common/ruoyi-common-cryptapi/pom.xml
new file mode 100644
index 0000000..ee0c577
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-common-cryptapi</artifactId>
+
+    <description>
+        ruoyi-common-cryptapi 鎺ュ彛璇锋眰鍙傛暟鍔犲瘑妯″潡
+    </description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-crypto</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java
new file mode 100644
index 0000000..2e2bdee
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/annotation/ApiDecrypt.java
@@ -0,0 +1,15 @@
+package org.dromara.cryptapi.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 褰撴爣鏈夊綋鍓嶆敞瑙g殑鎺ュ彛锛屾帴鍙g┛鍙備负鍔犲瘑瀛楃涓诧紝杩涜瑙e瘑鍚庝负dto瀵硅薄锛� 涓嶅奖鍝嶅悗缁弬鏁版牎楠屻��
+ * @author wdhcr
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ApiDecrypt {
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java
new file mode 100644
index 0000000..c74339b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/config/ApiDecryptConfig.java
@@ -0,0 +1,47 @@
+package org.dromara.cryptapi.config;
+
+import cn.hutool.core.collection.CollectionUtil;
+import jakarta.servlet.DispatcherType;
+import lombok.RequiredArgsConstructor;
+import org.dromara.cryptapi.filter.CryptoFilter;
+import org.dromara.cryptapi.handler.DecryptUrlHandler;
+import org.dromara.cryptapi.properties.ApiDecryptProperties;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+
+import java.util.HashMap;
+import java.util.List;
+
+@AutoConfiguration
+@RequiredArgsConstructor
+@EnableConfigurationProperties(ApiDecryptProperties.class)
+public class ApiDecryptConfig {
+
+    private final DecryptUrlHandler decryptUrlHandler;
+
+    private final ApiDecryptProperties apiDecryptProperties;
+
+    @Bean
+    public FilterRegistrationBean<CryptoFilter> cryptoFilterRegistration() {
+        FilterRegistrationBean<CryptoFilter> registration = new FilterRegistrationBean<>();
+        registration.setDispatcherTypes(DispatcherType.REQUEST);
+        registration.setFilter(new CryptoFilter());
+        List<String> urls = decryptUrlHandler.getUrls();
+        if (CollectionUtil.isNotEmpty(urls) || apiDecryptProperties.getEnable()) {
+            registration.setEnabled(true);
+            registration.addUrlPatterns(urls.toArray(new String[0]));
+        } else {
+            registration.setEnabled(false);
+        }
+        registration.setName("cryptoFilter");
+        HashMap<String, String> param = new HashMap<>();
+        param.put(CryptoFilter.CRYPTO_PUBLIC_KEY, apiDecryptProperties.getPublicKey());
+        param.put(CryptoFilter.CRYPTO_PRIVATE_KEY, apiDecryptProperties.getPrivateKey());
+        param.put(CryptoFilter.CRYPTO_HEADER_FLAG, apiDecryptProperties.getHeaderFlag());
+        registration.setInitParameters(param);
+        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
+        return registration;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java
new file mode 100644
index 0000000..29b4f4b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/AesEncryptor.java
@@ -0,0 +1,57 @@
+package org.dromara.cryptapi.core;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
+import org.dromara.cryptapi.enums.EncodeType;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * AES绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class AesEncryptor {
+
+    private final AES aes;
+
+    public AesEncryptor(EncryptContext context) {
+        String password = context.getPassword();
+        if (StrUtil.isBlank(password)) {
+            throw new IllegalArgumentException("AES娌℃湁鑾峰緱绉橀挜淇℃伅");
+        }
+        // aes绠楁硶鐨勭閽ヨ姹傛槸16浣嶃��24浣嶃��32浣�
+        int[] array = {16, 24, 32};
+        if (!ArrayUtil.contains(array, password.length())) {
+            throw new IllegalArgumentException("AES绉橀挜闀垮害搴旇涓�16浣嶃��24浣嶃��32浣嶏紝瀹為檯涓�" + password.length() + "浣�");
+        }
+        aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
+    }
+
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return aes.encryptHex(value);
+        } else {
+            return aes.encryptBase64(value);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    public String decrypt(String value) {
+        return this.aes.decryptStr(value);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java
new file mode 100644
index 0000000..76804ad
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/EncryptContext.java
@@ -0,0 +1,35 @@
+package org.dromara.cryptapi.core;
+
+import lombok.Data;
+import org.dromara.cryptapi.enums.EncodeType;
+
+/**
+ * 鍔犲瘑涓婁笅鏂� 鐢ㄤ簬encryptor浼犻�掑繀瑕佺殑鍙傛暟銆�
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+@Data
+public class EncryptContext {
+
+    /**
+     * 瀹夊叏绉橀挜
+     */
+    private String password;
+
+    /**
+     * 鍏挜
+     */
+    private String publicKey;
+
+    /**
+     * 绉侀挜
+     */
+    private String privateKey;
+
+    /**
+     * 缂栫爜鏂瑰紡锛宐ase64/hex
+     */
+    private EncodeType encode;
+
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java
new file mode 100644
index 0000000..9f8806d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/core/RsaEncryptor.java
@@ -0,0 +1,52 @@
+package org.dromara.cryptapi.core;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.cryptapi.enums.EncodeType;
+
+
+/**
+ * RSA绠楁硶瀹炵幇
+ *
+ * @author 鑰侀┈
+ * @version 4.6.0
+ */
+public class RsaEncryptor {
+
+    private final RSA rsa;
+
+    public RsaEncryptor(EncryptContext context) {
+        String privateKey = context.getPrivateKey();
+        String publicKey = context.getPublicKey();
+        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
+            throw new IllegalArgumentException("RSA鍏閽ュ潎闇�瑕佹彁渚涳紝鍏挜鍔犲瘑锛岀閽ヨВ瀵嗐��");
+        }
+        this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
+    }
+
+    /**
+     * 鍔犲瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     * @param encodeType 鍔犲瘑鍚庣殑缂栫爜鏍煎紡
+     */
+    public String encrypt(String value, EncodeType encodeType) {
+        if (encodeType == EncodeType.HEX) {
+            return rsa.encryptHex(value, KeyType.PublicKey);
+        } else {
+            return rsa.encryptBase64(value, KeyType.PublicKey);
+        }
+    }
+
+    /**
+     * 瑙e瘑
+     *
+     * @param value      寰呭姞瀵嗗瓧绗︿覆
+     */
+    public String decrypt(String value) {
+        return this.rsa.decryptStr(value, KeyType.PrivateKey);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java
new file mode 100644
index 0000000..7ee356a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/enums/EncodeType.java
@@ -0,0 +1,13 @@
+package org.dromara.cryptapi.enums;
+
+public enum EncodeType {
+    /**
+     * base64缂栫爜
+     */
+    BASE64,
+
+    /**
+     * 16杩涘埗缂栫爜
+     */
+    HEX
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java
new file mode 100644
index 0000000..b96e74d
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/CryptoFilter.java
@@ -0,0 +1,54 @@
+package org.dromara.cryptapi.filter;
+
+import jakarta.servlet.*;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.SneakyThrows;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.cryptapi.core.EncryptContext;
+import org.dromara.cryptapi.core.RsaEncryptor;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+
+import java.util.Objects;
+
+
+/**
+ * Crypto 杩囨护鍣�
+ *
+ * @author wdhcr
+ */
+public class CryptoFilter implements Filter {
+
+    public static final String CRYPTO_PUBLIC_KEY = "publicKey";
+    public static final String CRYPTO_PRIVATE_KEY = "privateKey";
+    public static final String CRYPTO_HEADER_FLAG = "headerFlag";
+    private RsaEncryptor rsaEncryptor;
+    private String headerFlag;
+
+
+    @Override
+    public void init(FilterConfig filterConfig) {
+        EncryptContext encryptContext = new EncryptContext();
+        encryptContext.setPublicKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PUBLIC_KEY));
+        encryptContext.setPrivateKey(filterConfig.getInitParameter(CryptoFilter.CRYPTO_PRIVATE_KEY));
+        headerFlag = filterConfig.getInitParameter(CryptoFilter.CRYPTO_HEADER_FLAG);
+        rsaEncryptor = new RsaEncryptor(encryptContext);
+    }
+
+    @SneakyThrows
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
+        ServletRequest requestWrapper = null;
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)
+            && (HttpMethod.PUT.matches(httpServletRequest.getMethod()) || HttpMethod.POST.matches(httpServletRequest.getMethod()))) {
+            requestWrapper = new DecryptRequestBodyWrapper(httpServletRequest, rsaEncryptor, headerFlag);
+        }
+        chain.doFilter(Objects.requireNonNullElse(requestWrapper, request), response);
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java
new file mode 100644
index 0000000..8d014c8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/filter/DecryptRequestBodyWrapper.java
@@ -0,0 +1,103 @@
+package org.dromara.cryptapi.filter;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.io.IoUtil;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.exception.base.BaseException;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.cryptapi.core.AesEncryptor;
+import org.dromara.cryptapi.core.EncryptContext;
+import org.dromara.cryptapi.core.RsaEncryptor;
+import org.dromara.cryptapi.enums.EncodeType;
+import org.springframework.http.MediaType;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 瑙e瘑璇锋眰鍙傛暟宸ュ叿绫�
+ *
+ * @author wdhcr
+ */
+public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper {
+
+    private final byte[] body;
+
+    public DecryptRequestBodyWrapper(HttpServletRequest request, RsaEncryptor rsaEncryptor, String headerFlag) throws IOException {
+        super(request);
+        String requestRsa = request.getHeader(headerFlag);
+        if (StringUtils.isEmpty(requestRsa)) {
+            throw new BaseException("鍔犲瘑AES鐨勫姩鎬佸瘑鐮佷笉鑳戒负绌�");
+        }
+        String decryptAes = new String(Base64.decode(rsaEncryptor.decrypt(requestRsa)));
+        request.setCharacterEncoding(Constants.UTF8);
+        byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false);
+        String requestBody = StringUtils.toEncodedString(readBytes, StandardCharsets.UTF_8);
+        EncryptContext encryptContext = new EncryptContext();
+        encryptContext.setPassword(decryptAes);
+        encryptContext.setEncode(EncodeType.BASE64);
+        AesEncryptor aesEncryptor = new AesEncryptor(encryptContext);
+        String decryptBody = aesEncryptor.decrypt(requestBody);
+        body = decryptBody.getBytes(StandardCharsets.UTF_8);
+    }
+
+    @Override
+    public BufferedReader getReader() {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+
+    @Override
+    public int getContentLength() {
+        return body.length;
+    }
+
+    @Override
+    public long getContentLengthLong() {
+        return body.length;
+    }
+
+    @Override
+    public String getContentType() {
+        return MediaType.APPLICATION_JSON_VALUE;
+    }
+
+
+    @Override
+    public ServletInputStream getInputStream() {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+            @Override
+            public int read() {
+                return bais.read();
+            }
+
+            @Override
+            public int available() {
+                return body.length;
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+
+            }
+        };
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java
new file mode 100644
index 0000000..cf01ea7
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/handler/DecryptUrlHandler.java
@@ -0,0 +1,55 @@
+package org.dromara.cryptapi.handler;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ReUtil;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import org.dromara.cryptapi.annotation.ApiDecrypt;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * 鑾峰彇闇�瑕佽В瀵嗙殑Url閰嶇疆
+ *
+ * @author wdhcr
+ */
+@Data
+@Component
+@RequiredArgsConstructor
+public class DecryptUrlHandler implements InitializingBean {
+
+    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)}");
+
+    private List<String> urls = new ArrayList<>();
+
+    private final RequestMappingHandlerMapping requestMappingHandlerMapping;
+
+    @Override
+    public void afterPropertiesSet() {
+        Set<String> set = new HashSet<>();
+        Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();
+        List<RequestMappingInfo> requestMappingInfos = map.entrySet().stream().filter(item -> {
+            HandlerMethod method = item.getValue();
+            ApiDecrypt decrypt = method.getMethodAnnotation(ApiDecrypt.class);
+            // 鏍囨湁瑙e瘑娉ㄨВ鐨勫苟涓旀槸post 鎴栬�卲ut 璇锋眰鐨刪andler
+            return decrypt != null && CollectionUtil.containsAny(item.getKey().getMethodsCondition().getMethods(), Arrays.asList(RequestMethod.PUT, RequestMethod.POST));
+        }).map(Map.Entry::getKey).toList();
+        requestMappingInfos.forEach(info -> {
+            // 鑾峰彇娉ㄨВ涓婅竟鐨� path 鏇夸唬 path variable 涓� *
+            Optional.ofNullable(info.getPathPatternsCondition())
+                .map(PathPatternsRequestCondition::getPatterns)
+                .orElseGet(HashSet::new)
+                .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
+        });
+        urls.addAll(set);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java
new file mode 100644
index 0000000..f7dc6b0
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/java/org/dromara/cryptapi/properties/ApiDecryptProperties.java
@@ -0,0 +1,34 @@
+package org.dromara.cryptapi.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * api瑙e瘑灞炴�ч厤缃被
+ * @author wdhcr
+ */
+@Data
+@ConfigurationProperties(prefix = "api-decrypt")
+public class ApiDecryptProperties {
+
+    /**
+     * 鍔犲瘑寮�鍏�
+     */
+    private Boolean enable;
+
+    /**
+     * 澶撮儴鏍囪瘑
+     */
+    private String headerFlag;
+
+
+    /**
+     * 鍏挜
+     */
+    private String publicKey;
+
+    /**
+     * 绉侀挜
+     */
+    private String privateKey;
+}
diff --git a/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..533d4be
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+org.dromara.cryptapi.config.ApiDecryptConfig

--
Gitblit v1.9.3