com.pig4cloud
pigx-common-excel
diff --git a/pigx-common/pigx-common-encrypt-api/pom.xml b/pigx-common/pigx-common-encrypt-api/pom.xml
new file mode 100644
index 000000000..a51459fb2
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+
+ 4.0.0
+
+ com.pig4cloud
+ pigx-common
+ 4.5.0
+
+
+ pigx-common-encrypt-api
+ jar
+
+ pigx api 加解密
+
+
+
+ com.pig4cloud
+ pigx-common-core
+
+
+ cn.hutool
+ hutool-crypto
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/ApiEncryptAutoConfiguration.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/ApiEncryptAutoConfiguration.java
new file mode 100644
index 000000000..469e2c4cc
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/ApiEncryptAutoConfiguration.java
@@ -0,0 +1,39 @@
+package com.pig4cloud.pigx.common.api.encrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptParamConfiguration;
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptProperties;
+import com.pig4cloud.pigx.common.api.encrypt.core.ApiDecryptRequestBodyAdvice;
+import com.pig4cloud.pigx.common.api.encrypt.core.ApiEncryptResponseBodyAdvice;
+import com.pig4cloud.pigx.common.api.encrypt.core.DefaultSecretKeyResolver;
+import com.pig4cloud.pigx.common.api.encrypt.core.ISecretKeyResolver;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * api 配置加载类
+ *
+ * @author lengleng
+ * @date 2022/10/14
+ */
+@Configuration(proxyBeanMethods = false)
+@EnableConfigurationProperties(ApiEncryptProperties.class)
+@Import({ ApiEncryptParamConfiguration.class, ApiDecryptRequestBodyAdvice.class, ApiEncryptResponseBodyAdvice.class })
+@ConditionalOnProperty(value = ApiEncryptProperties.PREFIX + ".enable", havingValue = "true", matchIfMissing = true)
+public class ApiEncryptAutoConfiguration {
+
+ /**
+ * 默认的 key 获取策略
+ * @param apiEncryptProperties
+ * @return
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public ISecretKeyResolver secretKeyResolver(ApiEncryptProperties apiEncryptProperties) {
+ return new DefaultSecretKeyResolver(apiEncryptProperties);
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoAes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoAes.java
new file mode 100644
index 000000000..49f59bcef
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoAes.java
@@ -0,0 +1,22 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
+
+import com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt.ApiEncrypt;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ * AES加密解密注解
+ *
+ * @author Chill
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ApiEncrypt(EncryptType.AES)
+@ApiDecrypt(EncryptType.AES)
+public @interface ApiCryptoAes {
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoDes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoDes.java
new file mode 100644
index 000000000..bb5f839fd
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoDes.java
@@ -0,0 +1,22 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
+
+import com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt.ApiEncrypt;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ * DES加密解密注解
+ *
+ * @author Chill
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ApiEncrypt(EncryptType.DES)
+@ApiDecrypt(EncryptType.DES)
+public @interface ApiCryptoDes {
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoRsa.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoRsa.java
new file mode 100644
index 000000000..ad97ed06c
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/crypto/ApiCryptoRsa.java
@@ -0,0 +1,22 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
+
+import com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt.ApiEncrypt;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ * RSA加密解密注解
+ *
+ * @author Chill
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ApiEncrypt(EncryptType.RSA)
+@ApiDecrypt(EncryptType.RSA)
+public @interface ApiCryptoRsa {
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecrypt.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecrypt.java
new file mode 100644
index 000000000..e1d3566ed
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecrypt.java
@@ -0,0 +1,34 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ *
+ * 解密含有{@link org.springframework.web.bind.annotation.RequestBody}注解的参数请求数据,可用于整个控制类或者某个控制器上
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/7
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface ApiDecrypt {
+
+ /**
+ * 解密类型
+ * @return 类型
+ */
+ EncryptType value();
+
+ /**
+ * 私钥,用于某些需要单独配置私钥的方法,没有时读取全局配置的私钥
+ * @return 私钥
+ */
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptAes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptAes.java
new file mode 100644
index 000000000..b1f2929d9
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptAes.java
@@ -0,0 +1,29 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.*;
+
+/**
+ * aes 界面
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/7
+ * @see ApiDecrypt
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiDecrypt(EncryptType.AES)
+public @interface ApiDecryptAes {
+
+ /**
+ * Alias for {@link ApiDecrypt#secretKey()}.
+ * @return {String}
+ */
+ @AliasFor(annotation = ApiDecrypt.class)
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptDes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptDes.java
new file mode 100644
index 000000000..e60dbd7ec
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptDes.java
@@ -0,0 +1,26 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.*;
+
+/**
+ * @author licoy.cn
+ * @version 2018/9/7
+ * @see ApiDecrypt
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiDecrypt(EncryptType.DES)
+public @interface ApiDecryptDes {
+
+ /**
+ * Alias for {@link ApiDecrypt#secretKey()}.
+ * @return {String}
+ */
+ @AliasFor(annotation = ApiDecrypt.class)
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptRsa.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptRsa.java
new file mode 100644
index 000000000..c5afdeafe
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/decrypt/ApiDecryptRsa.java
@@ -0,0 +1,18 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ * @author licoy.cn
+ * @version 2018/9/7
+ * @see ApiDecrypt
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiDecrypt(EncryptType.RSA)
+public @interface ApiDecryptRsa {
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncrypt.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncrypt.java
new file mode 100644
index 000000000..b6ac3197e
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncrypt.java
@@ -0,0 +1,34 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ *
+ * 加密{@link org.springframework.web.bind.annotation.ResponseBody}响应数据,可用于整个控制类或者某个控制器上
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface ApiEncrypt {
+
+ /**
+ * 加密类型
+ * @return 类型
+ */
+ EncryptType value();
+
+ /**
+ * 私钥,用于某些需要单独配置私钥的方法,没有时读取全局配置的私钥
+ * @return 私钥
+ */
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptAes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptAes.java
new file mode 100644
index 000000000..9ff3e5e5e
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptAes.java
@@ -0,0 +1,29 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.*;
+
+/**
+ * aes 加密
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ * @see ApiEncrypt
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiEncrypt(EncryptType.AES)
+public @interface ApiEncryptAes {
+
+ /**
+ * Alias for {@link ApiEncrypt#secretKey()}.
+ * @return {String}
+ */
+ @AliasFor(annotation = ApiEncrypt.class)
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptDes.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptDes.java
new file mode 100644
index 000000000..c4345337f
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptDes.java
@@ -0,0 +1,29 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.*;
+
+/**
+ * des 加埋
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ * @see ApiEncrypt
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiEncrypt(EncryptType.DES)
+public @interface ApiEncryptDes {
+
+ /**
+ * Alias for {@link ApiEncrypt#secretKey()}.
+ * @return {String}
+ */
+ @AliasFor(annotation = ApiEncrypt.class)
+ String secretKey() default "";
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptRsa.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptRsa.java
new file mode 100644
index 000000000..b4186c6b0
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/annotation/encrypt/ApiEncryptRsa.java
@@ -0,0 +1,21 @@
+package com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import java.lang.annotation.*;
+
+/**
+ * rsa body 加密
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ * @see ApiEncrypt
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ApiEncrypt(EncryptType.RSA)
+public @interface ApiEncryptRsa {
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/CryptoInfoBean.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/CryptoInfoBean.java
new file mode 100644
index 000000000..9e25197eb
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/CryptoInfoBean.java
@@ -0,0 +1,30 @@
+package com.pig4cloud.pigx.common.api.encrypt.bean;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+/**
+ *
+ * 加密注解信息
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/6
+ */
+@Getter
+@RequiredArgsConstructor
+public class CryptoInfoBean {
+
+ /**
+ * 加密类型
+ */
+ private final EncryptType type;
+
+ /**
+ * 私钥
+ */
+ private final String secretKey;
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/DecryptHttpInputMessage.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/DecryptHttpInputMessage.java
new file mode 100644
index 000000000..91ff5293c
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/bean/DecryptHttpInputMessage.java
@@ -0,0 +1,27 @@
+package com.pig4cloud.pigx.common.api.encrypt.bean;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpInputMessage;
+
+import java.io.InputStream;
+
+/**
+ *
+ * 解密信息输入流
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/7
+ */
+@Getter
+@RequiredArgsConstructor
+public class DecryptHttpInputMessage implements HttpInputMessage {
+
+ private final InputStream body;
+
+ private final HttpHeaders headers;
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptParamConfiguration.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptParamConfiguration.java
new file mode 100644
index 000000000..6e6cc157c
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptParamConfiguration.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pig4cloud.pigx.common.api.encrypt.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.pig4cloud.pigx.common.api.encrypt.core.ApiDecryptParamResolver;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.List;
+
+/**
+ * api 签名自动配置
+ *
+ * @author L.cm
+ */
+@RequiredArgsConstructor
+@ConditionalOnProperty(value = ApiEncryptProperties.PREFIX + ".enable", havingValue = "true", matchIfMissing = true)
+public class ApiEncryptParamConfiguration implements WebMvcConfigurer {
+
+ private final ApiEncryptProperties apiEncryptProperties;
+
+ private final ObjectMapper objectMapper;
+
+ public void addArgumentResolvers(List argumentResolvers) {
+ argumentResolvers.add(new ApiDecryptParamResolver(apiEncryptProperties, objectMapper));
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptProperties.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptProperties.java
new file mode 100644
index 000000000..77d3eb4fc
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/config/ApiEncryptProperties.java
@@ -0,0 +1,54 @@
+package com.pig4cloud.pigx.common.api.encrypt.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * api 签名配置类
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/6
+ */
+@Getter
+@Setter
+@ConfigurationProperties(ApiEncryptProperties.PREFIX)
+public class ApiEncryptProperties {
+
+ /**
+ * 前缀
+ */
+ public static final String PREFIX = "security.api.encrypt";
+
+ /**
+ * 是否开启 api 签名
+ */
+ private boolean enable = true;
+
+ /**
+ * url的参数签名,传递的参数名。例如:/user?data=签名后的数据
+ */
+ private String paramName = "data";
+
+ /**
+ * body 内容 json key, 默认:encryption
+ */
+ private String bodyJsonKey = "encryption";
+
+ /**
+ * aes 密钥
+ */
+ private String aesKey;
+
+ /**
+ * des 密钥
+ */
+ private String desKey;
+
+ /**
+ * rsa 私钥
+ */
+ private String rsaPrivateKey;
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptParamResolver.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptParamResolver.java
new file mode 100644
index 000000000..b74dd57f0
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptParamResolver.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.bean.CryptoInfoBean;
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptProperties;
+import com.pig4cloud.pigx.common.api.encrypt.util.ApiCryptoUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+import java.lang.reflect.Parameter;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * param 参数 解析
+ *
+ * @author L.cm
+ */
+@RequiredArgsConstructor
+public class ApiDecryptParamResolver implements HandlerMethodArgumentResolver {
+
+ private final ApiEncryptProperties properties;
+
+ private final ObjectMapper objectMapper;
+
+ @Override
+ public boolean supportsParameter(MethodParameter parameter) {
+ return AnnotatedElementUtils.hasAnnotation(parameter.getParameter(), ApiDecrypt.class);
+ }
+
+ @Nullable
+ @Override
+ public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
+ NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
+ Parameter parameter = methodParameter.getParameter();
+ ApiDecrypt apiDecrypt = AnnotatedElementUtils.getMergedAnnotation(parameter, ApiDecrypt.class);
+ String text = webRequest.getParameter(properties.getParamName());
+ if (StrUtil.isBlank(text)) {
+ return null;
+ }
+ CryptoInfoBean infoBean = new CryptoInfoBean(apiDecrypt.value(), apiDecrypt.secretKey());
+ byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
+ byte[] decryptData = ApiCryptoUtil.decryptData(textBytes, infoBean);
+
+ return objectMapper.readValue(decryptData, parameter.getType());
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptRequestBodyAdvice.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptRequestBodyAdvice.java
new file mode 100644
index 000000000..0da2f1467
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiDecryptRequestBodyAdvice.java
@@ -0,0 +1,108 @@
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.bean.CryptoInfoBean;
+import com.pig4cloud.pigx.common.api.encrypt.bean.DecryptHttpInputMessage;
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptProperties;
+import com.pig4cloud.pigx.common.api.encrypt.exception.DecryptBodyFailException;
+import com.pig4cloud.pigx.common.api.encrypt.util.ApiCryptoUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * 请求数据的加密信息解密处理
+ * 本类只对控制器参数中含有{@link org.springframework.web.bind.annotation.RequestBody}
+ * 以及package为cn.licoy.encryptbody.annotation.decrypt 下的注解有效
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/7
+ * @see RequestBodyAdvice
+ */
+@Slf4j
+@Order(1)
+@ControllerAdvice
+@RequiredArgsConstructor
+@ConditionalOnProperty(value = ApiEncryptProperties.PREFIX + ".enable", havingValue = "true", matchIfMissing = true)
+public class ApiDecryptRequestBodyAdvice implements RequestBodyAdvice {
+
+ private final ApiEncryptProperties properties;
+
+ private final ObjectMapper objectMapper;
+
+ @Override
+ public boolean supports(MethodParameter methodParameter, Type targetType,
+ Class extends HttpMessageConverter>> converterType) {
+ return AnnotationUtil.hasAnnotation(methodParameter.getMethod(), ApiDecrypt.class);
+ }
+
+ @Override
+ public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
+ Type targetType, Class extends HttpMessageConverter>> converterType) {
+ return body;
+ }
+
+ @Override
+ public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
+ Class extends HttpMessageConverter>> converterType) throws IOException {
+ // 判断 body 是否为空
+ InputStream messageBody = inputMessage.getBody();
+ if (messageBody.available() <= 0) {
+ return inputMessage;
+ }
+
+ CryptoInfoBean cryptoInfoBean = ApiCryptoUtil.getDecryptInfo(parameter);
+ if (cryptoInfoBean == null) {
+ throw new DecryptBodyFailException("获取解密注解配置为空");
+ }
+ // base64 byte array
+ byte[] bodyByteArray = StreamUtils.copyToByteArray(messageBody);
+ // body 内容 json key, 默认:data {"data":"base64加密字符串"}
+ String bodyJsonKey = properties.getBodyJsonKey();
+
+ byte[] decryptedBody = null;
+ if (StrUtil.isBlank(bodyJsonKey)) {
+ decryptedBody = ApiCryptoUtil.decryptData(bodyByteArray, cryptoInfoBean);
+ }
+ else {
+
+ Map data = objectMapper.readValue(bodyByteArray, Map.class);
+ String content = (String) data.get(bodyJsonKey);
+ if (content != null) {
+ decryptedBody = ApiCryptoUtil.decryptData(content.getBytes(StandardCharsets.UTF_8), cryptoInfoBean);
+ }
+ }
+ if (decryptedBody == null) {
+ throw new DecryptBodyFailException(
+ "Decryption error, " + "please check if the selected source data is encrypted correctly."
+ + " (解密错误,请检查选择的源数据的加密方式是否正确。)");
+ }
+ InputStream inputStream = new ByteArrayInputStream(decryptedBody);
+ return new DecryptHttpInputMessage(inputStream, inputMessage.getHeaders());
+ }
+
+ @Override
+ public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
+ Class extends HttpMessageConverter>> converterType) {
+ return body;
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiEncryptResponseBodyAdvice.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiEncryptResponseBodyAdvice.java
new file mode 100644
index 000000000..00fab9fe6
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ApiEncryptResponseBodyAdvice.java
@@ -0,0 +1,85 @@
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt.ApiEncrypt;
+import com.pig4cloud.pigx.common.api.encrypt.bean.CryptoInfoBean;
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptProperties;
+import com.pig4cloud.pigx.common.api.encrypt.exception.EncryptBodyFailException;
+import com.pig4cloud.pigx.common.api.encrypt.util.ApiCryptoUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.lang.Nullable;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 响应数据的加密处理
+ * 本类只对控制器参数中含有{@link org.springframework.web.bind.annotation.ResponseBody}
+ * 或者控制类上含有{@link org.springframework.web.bind.annotation.RestController}
+ * 以及package为cn.licoy.encryptbody.annotation.encrypt 下的注解有效
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ * @see ResponseBodyAdvice
+ */
+@Slf4j
+@Order(1)
+@ControllerAdvice
+@RequiredArgsConstructor
+@ConditionalOnProperty(value = ApiEncryptProperties.PREFIX + ".enable", havingValue = "true", matchIfMissing = true)
+public class ApiEncryptResponseBodyAdvice implements ResponseBodyAdvice {
+
+ private final ApiEncryptProperties properties;
+
+ private final ObjectMapper objectMapper;
+
+ @Override
+ public boolean supports(MethodParameter returnType, Class converterType) {
+ return AnnotationUtil.hasAnnotation(returnType.getMethod(), ApiEncrypt.class);
+ }
+
+ @Nullable
+ @Override
+ public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
+ Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+ if (body == null) {
+ return null;
+ }
+
+ CryptoInfoBean cryptoInfoBean = ApiCryptoUtil.getEncryptInfo(returnType);
+ if (cryptoInfoBean == null) {
+ throw new EncryptBodyFailException();
+ }
+
+ byte[] bodyJsonBytes;
+ try {
+ bodyJsonBytes = objectMapper.writeValueAsBytes(body);
+ }
+ catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+
+ // body 内容 json key, 默认:data {"data":"base64加密字符串"}
+ String bodyJsonKey = properties.getBodyJsonKey();
+ if (StrUtil.isBlank(bodyJsonKey)) {
+ return ApiCryptoUtil.encryptData(bodyJsonBytes, cryptoInfoBean);
+ }
+ Map data = new HashMap<>(2);
+ data.put(bodyJsonKey, ApiCryptoUtil.encryptData(bodyJsonBytes, cryptoInfoBean));
+ return data;
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/DefaultSecretKeyResolver.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/DefaultSecretKeyResolver.java
new file mode 100644
index 000000000..54705382a
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/DefaultSecretKeyResolver.java
@@ -0,0 +1,31 @@
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import com.pig4cloud.pigx.common.api.encrypt.config.ApiEncryptProperties;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import lombok.RequiredArgsConstructor;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 默认的密钥处理器
+ *
+ * @author L.cm
+ */
+@RequiredArgsConstructor
+public class DefaultSecretKeyResolver implements ISecretKeyResolver {
+
+ private final ApiEncryptProperties properties;
+
+ @Override
+ public String getSecretKey(HttpServletRequest request, EncryptType encryptType) {
+ switch (encryptType) {
+ case DES:
+ return properties.getDesKey();
+ case RSA:
+ return properties.getRsaPrivateKey();
+ default:
+ return properties.getAesKey();
+ }
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ISecretKeyResolver.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ISecretKeyResolver.java
new file mode 100644
index 000000000..0dd9cc5a2
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/ISecretKeyResolver.java
@@ -0,0 +1,22 @@
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 解析加密密钥
+ *
+ * @author L.cm
+ */
+public interface ISecretKeyResolver {
+
+ /**
+ * 获取租户对应的加、解密密钥
+ * @param request HttpServletRequest
+ * @param encryptType 加解密类型
+ * @return 密钥
+ */
+ String getSecretKey(HttpServletRequest request, EncryptType encryptType);
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/package-info.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/package-info.java
new file mode 100644
index 000000000..688ae992d
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/core/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@NonNullApi
+@NonNullFields
+package com.pig4cloud.pigx.common.api.encrypt.core;
+
+import org.springframework.lang.NonNullApi;
+import org.springframework.lang.NonNullFields;
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/enums/EncryptType.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/enums/EncryptType.java
new file mode 100644
index 000000000..3481b236b
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/enums/EncryptType.java
@@ -0,0 +1,19 @@
+package com.pig4cloud.pigx.common.api.encrypt.enums;
+
+/**
+ *
+ * 加密方式
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/4
+ */
+public enum EncryptType {
+
+ /**
+ * 加密方式
+ */
+ DES, AES, RSA
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/DecryptBodyFailException.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/DecryptBodyFailException.java
new file mode 100644
index 000000000..b2d2df1af
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/DecryptBodyFailException.java
@@ -0,0 +1,17 @@
+package com.pig4cloud.pigx.common.api.encrypt.exception;
+
+/**
+ *
+ * 解密数据失败异常
+ *
+ *
+ * @author licoy.cn
+ * @version 2018/9/6
+ */
+public class DecryptBodyFailException extends RuntimeException {
+
+ public DecryptBodyFailException(String message) {
+ super(message);
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptBodyFailException.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptBodyFailException.java
new file mode 100644
index 000000000..68dee10e5
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptBodyFailException.java
@@ -0,0 +1,21 @@
+package com.pig4cloud.pigx.common.api.encrypt.exception;
+
+/**
+ *
+ * 加密数据失败异常
+ *
+ *
+ * @author licoy.cn
+ * @version 2018/9/6
+ */
+public class EncryptBodyFailException extends RuntimeException {
+
+ public EncryptBodyFailException() {
+ super("Encrypted data failed. (加密数据失败)");
+ }
+
+ public EncryptBodyFailException(String message) {
+ super(message);
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptMethodNotFoundException.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptMethodNotFoundException.java
new file mode 100644
index 000000000..3e15e256a
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/EncryptMethodNotFoundException.java
@@ -0,0 +1,17 @@
+package com.pig4cloud.pigx.common.api.encrypt.exception;
+
+/**
+ *
+ * 加密方式未找到或未定义异常
+ *
+ *
+ * @author licoy.cn
+ * @version 2018/9/6
+ */
+public class EncryptMethodNotFoundException extends RuntimeException {
+
+ public EncryptMethodNotFoundException() {
+ super("Encryption method is not defined. (加密方式未定义)");
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/KeyNotConfiguredException.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/KeyNotConfiguredException.java
new file mode 100644
index 000000000..b7cb6b65d
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/exception/KeyNotConfiguredException.java
@@ -0,0 +1,18 @@
+package com.pig4cloud.pigx.common.api.encrypt.exception;
+
+/**
+ *
+ * 未配置KEY运行时异常
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/6
+ */
+public class KeyNotConfiguredException extends RuntimeException {
+
+ public KeyNotConfiguredException(String message) {
+ super(message);
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/util/ApiCryptoUtil.java b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/util/ApiCryptoUtil.java
new file mode 100644
index 000000000..17a06683e
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/java/com/pig4cloud/pigx/common/api/encrypt/util/ApiCryptoUtil.java
@@ -0,0 +1,141 @@
+package com.pig4cloud.pigx.common.api.encrypt.util;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.Mode;
+import cn.hutool.crypto.Padding;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.symmetric.AES;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.decrypt.ApiDecrypt;
+import com.pig4cloud.pigx.common.api.encrypt.annotation.encrypt.ApiEncrypt;
+import com.pig4cloud.pigx.common.api.encrypt.bean.CryptoInfoBean;
+import com.pig4cloud.pigx.common.api.encrypt.core.ISecretKeyResolver;
+import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
+import com.pig4cloud.pigx.common.api.encrypt.exception.EncryptBodyFailException;
+import com.pig4cloud.pigx.common.api.encrypt.exception.EncryptMethodNotFoundException;
+import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
+import com.pig4cloud.pigx.common.core.util.WebUtils;
+import lombok.experimental.UtilityClass;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
+
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ *
+ * 辅助检测工具类
+ *
+ *
+ * @author licoy.cn
+ * @author L.cm
+ * @version 2018/9/7
+ */
+@UtilityClass
+public class ApiCryptoUtil {
+
+ /**
+ * 获取方法控制器上的加密注解信息
+ * @param methodParameter 控制器方法
+ * @return 加密注解信息
+ */
+ @Nullable
+ public static CryptoInfoBean getEncryptInfo(MethodParameter methodParameter) {
+ ApiEncrypt encryptBody = AnnotatedElementUtils.findMergedAnnotation(methodParameter.getMethod(),
+ ApiEncrypt.class);
+ if (encryptBody == null) {
+ return null;
+ }
+ return new CryptoInfoBean(encryptBody.value(), encryptBody.secretKey());
+ }
+
+ /**
+ * 获取方法控制器上的解密注解信息
+ * @param methodParameter 控制器方法
+ * @return 加密注解信息
+ */
+ @Nullable
+ public static CryptoInfoBean getDecryptInfo(MethodParameter methodParameter) {
+ ApiDecrypt decryptBody = AnnotatedElementUtils.findMergedAnnotation(methodParameter.getMethod(),
+ ApiDecrypt.class);
+ if (decryptBody == null) {
+ return null;
+ }
+ return new CryptoInfoBean(decryptBody.value(), decryptBody.secretKey());
+ }
+
+ /**
+ * 选择加密方式并进行加密
+ * @param jsonData json 数据
+ * @param infoBean 加密信息
+ * @return 加密结果
+ */
+ public static String encryptData(byte[] jsonData, CryptoInfoBean infoBean) {
+ EncryptType type = infoBean.getType();
+ if (type == null) {
+ throw new EncryptMethodNotFoundException();
+ }
+
+ String secretKey = infoBean.getSecretKey();
+ if (StrUtil.isBlank(secretKey)) {
+ secretKey = SpringContextHolder.getBean(ISecretKeyResolver.class).getSecretKey(WebUtils.getRequest(), type);
+ }
+ Assert.hasText(secretKey, type + " key is not configured (未配置" + type + ")");
+
+ if (type == EncryptType.DES) {
+
+ return SecureUtil.des(secretKey.getBytes(StandardCharsets.UTF_8)).encryptBase64(jsonData);
+ }
+ if (type == EncryptType.AES) {
+ // 构建前端对应解密AES 因子
+ AES aes = new AES(Mode.CFB, Padding.NoPadding, new SecretKeySpec(secretKey.getBytes(), "AES"),
+ new IvParameterSpec(secretKey.getBytes()));
+
+ return aes.encryptBase64(jsonData);
+ }
+ if (type == EncryptType.RSA) {
+ return SecureUtil.rsa(secretKey.getBytes(StandardCharsets.UTF_8), null).encryptBase64(jsonData,
+ KeyType.PrivateKey);
+ }
+ throw new EncryptBodyFailException();
+ }
+
+ /**
+ * 选择加密方式并进行解密
+ * @param bodyData byte array
+ * @param infoBean 加密信息
+ * @return 解密结果
+ */
+ public static byte[] decryptData(byte[] bodyData, CryptoInfoBean infoBean) {
+ EncryptType type = infoBean.getType();
+ if (type == null) {
+ throw new EncryptMethodNotFoundException();
+ }
+
+ String secretKey = infoBean.getSecretKey();
+ if (StrUtil.isBlank(secretKey)) {
+ secretKey = SpringContextHolder.getBean(ISecretKeyResolver.class).getSecretKey(WebUtils.getRequest(), type);
+ }
+ Assert.hasText(secretKey, type + " key is not configured (未配置" + type + ")");
+
+ if (type == EncryptType.AES) {
+ // 构建前端对应解密AES 因子
+ AES aes = new AES(Mode.CFB, Padding.NoPadding, new SecretKeySpec(secretKey.getBytes(), "AES"),
+ new IvParameterSpec(secretKey.getBytes()));
+ return aes.decrypt(StrUtil.str(bodyData, Charset.defaultCharset()));
+ }
+ if (type == EncryptType.DES) {
+ return SecureUtil.des(secretKey.getBytes(StandardCharsets.UTF_8)).decrypt(bodyData);
+ }
+ if (type == EncryptType.RSA) {
+ return SecureUtil.rsa(secretKey.getBytes(StandardCharsets.UTF_8), null).decrypt(bodyData,
+ KeyType.PrivateKey);
+ }
+ throw new EncryptMethodNotFoundException();
+ }
+
+}
diff --git a/pigx-common/pigx-common-encrypt-api/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-encrypt-api/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..bdf7e9a95
--- /dev/null
+++ b/pigx-common/pigx-common-encrypt-api/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.pig4cloud.pigx.common.api.encrypt.ApiEncryptAutoConfiguration
diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml
index 0c7922b42..2c8ced488 100644
--- a/pigx-common/pom.xml
+++ b/pigx-common/pom.xml
@@ -38,6 +38,7 @@
pigx-common-data
pigx-common-datasource
pigx-common-excel
+ pigx-common-encrypt-api
pigx-common-feign
pigx-common-gateway
pigx-common-gray