diff --git a/pigx-auth/src/main/resources/application.yml b/pigx-auth/src/main/resources/application.yml index ba232cd41..eeaf5b5fd 100644 --- a/pigx-auth/src/main/resources/application.yml +++ b/pigx-auth/src/main/resources/application.yml @@ -1,6 +1,12 @@ server: port: 3000 + +security: + api: + encrypt: + aesKey: 'pigxpigxpigxpigx' + spring: application: name: @artifactId@ @@ -13,4 +19,4 @@ spring: config: import: - optional:nacos:application-@profiles.active@.yml - - optional:nacos:${spring.application.name}-@profiles.active@.yml \ No newline at end of file + - optional:nacos:${spring.application.name}-@profiles.active@.yml diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 3b061b13f..0b079b186 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -137,6 +137,11 @@ pigx-common-websocket ${pigx.version} + + com.pig4cloud + pigx-common-encrypt-api + ${pigx.version} + 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> converterType) { + return AnnotationUtil.hasAnnotation(methodParameter.getMethod(), ApiDecrypt.class); + } + + @Override + public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, + Type targetType, Class> converterType) { + return body; + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, + Class> 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> 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