feat: initial iShare project code
This commit is contained in:
30
pigx-common/pigx-common-encrypt-api/pom.xml
Normal file
30
pigx-common/pigx-common-encrypt-api/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-encrypt-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<description>pigx api 加解密</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
|
||||
|
||||
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.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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
|
||||
|
||||
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.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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
|
||||
|
||||
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.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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.annotation.crypto;
|
||||
|
||||
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.enums.EncryptType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Sm4加密解密注解
|
||||
*
|
||||
* @author lengleng
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@ApiEncrypt(EncryptType.SM4)
|
||||
@ApiDecrypt(EncryptType.SM4)
|
||||
public @interface ApiCryptoSm4 {
|
||||
|
||||
}
|
||||
@@ -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.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 解密含有{@link org.springframework.web.bind.annotation.RequestBody}注解的参数请求数据,可用于整个控制类或者某个控制器上
|
||||
* </p>
|
||||
*
|
||||
* @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 "";
|
||||
|
||||
}
|
||||
@@ -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 "";
|
||||
|
||||
}
|
||||
@@ -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 "";
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* sm4 解密
|
||||
*
|
||||
* @author lengleng
|
||||
* @version 2023/8/30
|
||||
* @see ApiDecrypt
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ApiDecrypt(EncryptType.SM4)
|
||||
public @interface ApiDecryptSm4 {
|
||||
|
||||
/**
|
||||
* Alias for {@link ApiDecrypt#secretKey()}.
|
||||
* @return {String}
|
||||
*/
|
||||
@AliasFor(annotation = ApiDecrypt.class)
|
||||
String secretKey() default "";
|
||||
|
||||
}
|
||||
@@ -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.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 加密{@link org.springframework.web.bind.annotation.ResponseBody}响应数据,可用于整个控制类或者某个控制器上
|
||||
* </p>
|
||||
*
|
||||
* @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 "";
|
||||
|
||||
}
|
||||
@@ -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 "";
|
||||
|
||||
}
|
||||
@@ -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 "";
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* sm4 加密
|
||||
*
|
||||
* @author lengleng
|
||||
* @version 2023/8/30
|
||||
* @see ApiEncrypt
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ApiEncrypt(EncryptType.SM4)
|
||||
public @interface ApiEncryptSm4 {
|
||||
|
||||
/**
|
||||
* Alias for {@link ApiEncrypt#secretKey()}.
|
||||
* @return {String}
|
||||
*/
|
||||
@AliasFor(annotation = ApiEncrypt.class)
|
||||
String secretKey() default "";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.bean;
|
||||
|
||||
import com.pig4cloud.pigx.common.api.encrypt.enums.EncryptType;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 加密注解信息
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @author L.cm
|
||||
* @version 2018/9/6
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class CryptoInfoBean {
|
||||
|
||||
/**
|
||||
* 加密类型
|
||||
*/
|
||||
private final EncryptType type;
|
||||
|
||||
/**
|
||||
* 私钥
|
||||
*/
|
||||
private final String secretKey;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 解密信息输入流
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new ApiDecryptParamResolver(apiEncryptProperties, objectMapper));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
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 = "encryption";
|
||||
|
||||
/**
|
||||
* body 内容 json key, 默认:encryption
|
||||
*/
|
||||
private String bodyJsonKey = "encryption";
|
||||
|
||||
/**
|
||||
* aes 密钥
|
||||
*/
|
||||
private String aesKey;
|
||||
|
||||
/**
|
||||
* des 密钥
|
||||
*/
|
||||
private String desKey;
|
||||
|
||||
/**
|
||||
* sm4 密钥
|
||||
*/
|
||||
private String sm4Key;
|
||||
|
||||
/**
|
||||
* rsa 私钥
|
||||
*/
|
||||
private String rsaPrivateKey;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 请求数据的加密信息解密处理<br>
|
||||
* 本类只对控制器参数中含有<strong>{@link org.springframework.web.bind.annotation.RequestBody}</strong>
|
||||
* 以及package为<strong><code>cn.licoy.encryptbody.annotation.decrypt</code></strong>下的注解有效
|
||||
*
|
||||
* @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<String, Object> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 响应数据的加密处理<br>
|
||||
* 本类只对控制器参数中含有<strong>{@link org.springframework.web.bind.annotation.ResponseBody}</strong>
|
||||
* 或者控制类上含有<strong>{@link org.springframework.web.bind.annotation.RestController}</strong>
|
||||
* 以及package为<strong><code>cn.licoy.encryptbody.annotation.encrypt</code></strong>下的注解有效
|
||||
*
|
||||
* @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<Object> {
|
||||
|
||||
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<String, Object> data = new HashMap<>(2);
|
||||
data.put(bodyJsonKey, ApiCryptoUtil.encryptData(bodyJsonBytes, cryptoInfoBean));
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* 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;
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.enums;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 加密方式
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @author L.cm
|
||||
* @version 2018/9/4
|
||||
*/
|
||||
public enum EncryptType {
|
||||
|
||||
/**
|
||||
* 加密方式
|
||||
*/
|
||||
DES, AES, RSA, SM4
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.exception;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 解密数据失败异常
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @version 2018/9/6
|
||||
*/
|
||||
public class DecryptBodyFailException extends RuntimeException {
|
||||
|
||||
public DecryptBodyFailException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.exception;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 加密数据失败异常
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @version 2018/9/6
|
||||
*/
|
||||
public class EncryptBodyFailException extends RuntimeException {
|
||||
|
||||
public EncryptBodyFailException() {
|
||||
super("Encrypted data failed. (加密数据失败)");
|
||||
}
|
||||
|
||||
public EncryptBodyFailException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.exception;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 加密方式未找到或未定义异常
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @version 2018/9/6
|
||||
*/
|
||||
public class EncryptMethodNotFoundException extends RuntimeException {
|
||||
|
||||
public EncryptMethodNotFoundException() {
|
||||
super("Encryption method is not defined. (加密方式未定义)");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.exception;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 未配置KEY运行时异常
|
||||
* </p>
|
||||
*
|
||||
* @author licoy.cn
|
||||
* @author L.cm
|
||||
* @version 2018/9/6
|
||||
*/
|
||||
public class KeyNotConfiguredException extends RuntimeException {
|
||||
|
||||
public KeyNotConfiguredException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.pig4cloud.pigx.common.api.encrypt.util;
|
||||
|
||||
import cn.hutool.core.util.HexUtil;
|
||||
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.SmUtil;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 辅助检测工具类
|
||||
* </p>
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
if (type == EncryptType.SM4) {
|
||||
return SmUtil.sm4(HexUtil.decodeHex(secretKey)).encryptHex(jsonData);
|
||||
}
|
||||
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 = new AES(Mode.CFB, Padding.NoPadding,
|
||||
new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES"),
|
||||
new IvParameterSpec(secretKey.getBytes(StandardCharsets.UTF_8)));
|
||||
return aes.decrypt(StrUtil.str(bodyData, StandardCharsets.UTF_8));
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (type == EncryptType.SM4) {
|
||||
return SmUtil.sm4(HexUtil.decodeHex(secretKey)).decryptStr(StrUtil.str(bodyData, Charset.defaultCharset()))
|
||||
.getBytes();
|
||||
}
|
||||
|
||||
throw new EncryptMethodNotFoundException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
com.pig4cloud.pigx.common.api.encrypt.ApiEncryptAutoConfiguration
|
||||
Reference in New Issue
Block a user