diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 39731b1a..3d121c05 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -87,6 +87,12 @@
JustAuth
+
+
+ org.dromara
+ ruoyi-common-cryptapi
+
+
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index fcc18650..878a9c30 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -173,6 +173,16 @@ mybatis-encryptor:
publicKey:
privateKey:
+# api接口加密
+api-decrypt:
+ # 是否开启全局接口加密
+ enable: false
+ # AES 加密头标识
+ headerFlag: AES
+ # 公私钥 非对称算法的公私钥 如:SM2,RSA
+ publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
+ privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
+
springdoc:
api-docs:
# 是否开启接口文档
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 45493d3e..e77ea237 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -33,6 +33,7 @@
ruoyi-common-encrypt
ruoyi-common-tenant
ruoyi-common-websocket
+ ruoyi-common-cryptapi
ruoyi-common
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index 93d11897..5014954d 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -171,6 +171,13 @@
ruoyi-common-websocket
${revision}
+
+
+
+ org.dromara
+ ruoyi-common-cryptapi
+ ${revision}
+
diff --git a/ruoyi-common/ruoyi-common-cryptapi/pom.xml b/ruoyi-common/ruoyi-common-cryptapi/pom.xml
new file mode 100644
index 00000000..ee0c5777
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-cryptapi/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ org.dromara
+ ruoyi-common
+ ${revision}
+
+ 4.0.0
+
+ ruoyi-common-cryptapi
+
+
+ ruoyi-common-cryptapi 接口请求参数加密模块
+
+
+
+
+
+ org.dromara
+ ruoyi-common-core
+
+
+ cn.hutool
+ hutool-crypto
+
+
+ org.springframework
+ spring-webmvc
+
+
+
+
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 00000000..2e2bdee7
--- /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;
+
+/**
+ * 当标有当前注解的接口,接口穿参为加密字符串,进行解密后为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 00000000..c74339b8
--- /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 cryptoFilterRegistration() {
+ FilterRegistrationBean registration = new FilterRegistrationBean<>();
+ registration.setDispatcherTypes(DispatcherType.REQUEST);
+ registration.setFilter(new CryptoFilter());
+ List 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 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 00000000..29b4f4b4
--- /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);
+ }
+ }
+
+ /**
+ * 解密
+ *
+ * @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 00000000..76804adb
--- /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;
+
+ /**
+ * 编码方式,base64/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 00000000..9f8806d1
--- /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);
+ }
+ }
+
+ /**
+ * 解密
+ *
+ * @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 00000000..7ee356af
--- /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 00000000..b96e74db
--- /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 00000000..8d014c8d
--- /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;
+
+/**
+ * 解密请求参数工具类
+ *
+ * @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 00000000..cf01ea79
--- /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 urls = new ArrayList<>();
+
+ private final RequestMappingHandlerMapping requestMappingHandlerMapping;
+
+ @Override
+ public void afterPropertiesSet() {
+ Set set = new HashSet<>();
+ Map map = requestMappingHandlerMapping.getHandlerMethods();
+ List requestMappingInfos = map.entrySet().stream().filter(item -> {
+ HandlerMethod method = item.getValue();
+ ApiDecrypt decrypt = method.getMethodAnnotation(ApiDecrypt.class);
+ // 标有解密注解的并且是post 或者put 请求的handler
+ 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 00000000..f7dc6b0b
--- /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解密属性配置类
+ * @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 00000000..533d4be7
--- /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