mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-11-04 09:01:40 +08:00 
			
		
		
		
	refactor(security/crypto):重构加/解密模块业务逻辑,封装 EncryptHelper 工具类,提供统一的加/解密方法,方便使用者灵活处理加/解密
This commit is contained in:
		@@ -1,3 +1,19 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					 * <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 top.continew.starter.core.util;
 | 
					package top.continew.starter.core.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.hutool.core.collection.CollUtil;
 | 
					import cn.hutool.core.collection.CollUtil;
 | 
				
			||||||
@@ -70,7 +86,10 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
     * @param nodeParser     解析器,用于将输入节点转换为树节点
 | 
					     * @param nodeParser     解析器,用于将输入节点转换为树节点
 | 
				
			||||||
     * @return 构建好的树形结构列表
 | 
					     * @return 构建好的树形结构列表
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static <T, K> List<Tree<K>> build(List<T> list, K parentId, TreeNodeConfig treeNodeConfig, NodeParser<T, K> nodeParser) {
 | 
					    public static <T, K> List<Tree<K>> build(List<T> list,
 | 
				
			||||||
 | 
					                                             K parentId,
 | 
				
			||||||
 | 
					                                             TreeNodeConfig treeNodeConfig,
 | 
				
			||||||
 | 
					                                             NodeParser<T, K> nodeParser) {
 | 
				
			||||||
        if (CollUtil.isEmpty(list)) {
 | 
					        if (CollUtil.isEmpty(list)) {
 | 
				
			||||||
            return CollUtil.newArrayList();
 | 
					            return CollUtil.newArrayList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -88,7 +107,10 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
     * @param <K>         节点 ID 类型(如 Long、String)
 | 
					     * @param <K>         节点 ID 类型(如 Long、String)
 | 
				
			||||||
     * @return 构建完成的树形结构(可能包含多个顶级根节点)
 | 
					     * @return 构建完成的树形结构(可能包含多个顶级根节点)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list, Function<T, K> getId, Function<T, K> getParentId, NodeParser<T, K> parser) {
 | 
					    public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list,
 | 
				
			||||||
 | 
					                                                      Function<T, K> getId,
 | 
				
			||||||
 | 
					                                                      Function<T, K> getParentId,
 | 
				
			||||||
 | 
					                                                      NodeParser<T, K> parser) {
 | 
				
			||||||
        if (CollUtil.isEmpty(list)) {
 | 
					        if (CollUtil.isEmpty(list)) {
 | 
				
			||||||
            return CollUtil.newArrayList();
 | 
					            return CollUtil.newArrayList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -112,8 +134,11 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
     * @param parser         树节点属性映射器,用于将原始节点 T 转为 Tree 节点
 | 
					     * @param parser         树节点属性映射器,用于将原始节点 T 转为 Tree 节点
 | 
				
			||||||
     * @return 构建完成的树形结构(可能包含多个顶级根节点)
 | 
					     * @return 构建完成的树形结构(可能包含多个顶级根节点)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list, Function<T, K> getId, Function<T, K> getParentId,
 | 
					    public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list,
 | 
				
			||||||
                                                      TreeNodeConfig treeNodeConfig, NodeParser<T, K> parser) {
 | 
					                                                      Function<T, K> getId,
 | 
				
			||||||
 | 
					                                                      Function<T, K> getParentId,
 | 
				
			||||||
 | 
					                                                      TreeNodeConfig treeNodeConfig,
 | 
				
			||||||
 | 
					                                                      NodeParser<T, K> parser) {
 | 
				
			||||||
        if (CollUtil.isEmpty(list)) {
 | 
					        if (CollUtil.isEmpty(list)) {
 | 
				
			||||||
            return CollUtil.newArrayList();
 | 
					            return CollUtil.newArrayList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -121,8 +146,8 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
        rootParentIds.removeAll(CollUtils.mapToSet(list, getId));
 | 
					        rootParentIds.removeAll(CollUtils.mapToSet(list, getId));
 | 
				
			||||||
        // 构建每一个根 parentId 下的树,并合并成最终结果列表
 | 
					        // 构建每一个根 parentId 下的树,并合并成最终结果列表
 | 
				
			||||||
        return rootParentIds.stream()
 | 
					        return rootParentIds.stream()
 | 
				
			||||||
                .flatMap(rootParentId -> TreeUtil.build(list, rootParentId, treeNodeConfig, parser).stream())
 | 
					            .flatMap(rootParentId -> TreeUtil.build(list, rootParentId, treeNodeConfig, parser).stream())
 | 
				
			||||||
                .collect(Collectors.toList());
 | 
					            .collect(Collectors.toList());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -136,9 +161,7 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
        if (CollUtil.isEmpty(nodes)) {
 | 
					        if (CollUtil.isEmpty(nodes)) {
 | 
				
			||||||
            return CollUtil.newArrayList();
 | 
					            return CollUtil.newArrayList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return nodes.stream()
 | 
					        return nodes.stream().flatMap(TreeBuildUtils::extractLeafNodes).collect(Collectors.toList());
 | 
				
			||||||
            .flatMap(TreeBuildUtils::extractLeafNodes)
 | 
					 | 
				
			||||||
            .collect(Collectors.toList());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -153,8 +176,7 @@ public class TreeBuildUtils extends TreeUtil {
 | 
				
			|||||||
            return Stream.of(node);
 | 
					            return Stream.of(node);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // 递归调用,获取所有子节点的叶子节点
 | 
					            // 递归调用,获取所有子节点的叶子节点
 | 
				
			||||||
            return node.getChildren().stream()
 | 
					            return node.getChildren().stream().flatMap(TreeBuildUtils::extractLeafNodes);
 | 
				
			||||||
                .flatMap(TreeBuildUtils::extractLeafNodes);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,7 +105,9 @@ public abstract class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdD
 | 
				
			|||||||
        CrudTreeProperties treeProperties = crudProperties.getTree();
 | 
					        CrudTreeProperties treeProperties = crudProperties.getTree();
 | 
				
			||||||
        TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class);
 | 
					        TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class);
 | 
				
			||||||
        // 简单树(下拉列表)使用全局配置结构,复杂树(表格)使用局部配置
 | 
					        // 简单树(下拉列表)使用全局配置结构,复杂树(表格)使用局部配置
 | 
				
			||||||
        TreeNodeConfig treeNodeConfig = isSimple ? treeProperties.genTreeNodeConfig() : treeProperties.genTreeNodeConfig(treeField);
 | 
					        TreeNodeConfig treeNodeConfig = isSimple
 | 
				
			||||||
 | 
					            ? treeProperties.genTreeNodeConfig()
 | 
				
			||||||
 | 
					            : treeProperties.genTreeNodeConfig(treeField);
 | 
				
			||||||
        String valueGetter = CharSequenceUtil.genGetter(treeField.value());
 | 
					        String valueGetter = CharSequenceUtil.genGetter(treeField.value());
 | 
				
			||||||
        String parentIdKeyGetter = CharSequenceUtil.genGetter(treeField.parentIdKey());
 | 
					        String parentIdKeyGetter = CharSequenceUtil.genGetter(treeField.parentIdKey());
 | 
				
			||||||
        Function<L, Long> getId = createMethodReference(listClass, valueGetter);
 | 
					        Function<L, Long> getId = createMethodReference(listClass, valueGetter);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@ import java.lang.annotation.Target;
 | 
				
			|||||||
 * 字段加/解密注解
 | 
					 * 字段加/解密注解
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Target({ElementType.FIELD, ElementType.PARAMETER})
 | 
					@Target({ElementType.FIELD, ElementType.PARAMETER})
 | 
				
			||||||
@@ -37,7 +38,7 @@ public @interface FieldEncrypt {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 加密/解密算法
 | 
					     * 加密/解密算法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    Algorithm value() default Algorithm.AES;
 | 
					    Algorithm value() default Algorithm.DEFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 加密/解密处理器
 | 
					     * 加密/解密处理器
 | 
				
			||||||
@@ -51,4 +52,14 @@ public @interface FieldEncrypt {
 | 
				
			|||||||
     * 对称加密算法密钥
 | 
					     * 对称加密算法密钥
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    String password() default "";
 | 
					    String password() default "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 非对称加密算法公钥:RSA需要
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    String publicKey() default "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 非对称加密算法私钥:RSA需要
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    String privateKey() default "";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -27,11 +27,13 @@ import org.springframework.context.annotation.Bean;
 | 
				
			|||||||
import top.continew.starter.core.constant.PropertiesConstants;
 | 
					import top.continew.starter.core.constant.PropertiesConstants;
 | 
				
			||||||
import top.continew.starter.security.crypto.core.MyBatisDecryptInterceptor;
 | 
					import top.continew.starter.security.crypto.core.MyBatisDecryptInterceptor;
 | 
				
			||||||
import top.continew.starter.security.crypto.core.MyBatisEncryptInterceptor;
 | 
					import top.continew.starter.security.crypto.core.MyBatisEncryptInterceptor;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.utils.EncryptHelper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 加/解密自动配置
 | 
					 * 加/解密自动配置
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@AutoConfiguration
 | 
					@AutoConfiguration
 | 
				
			||||||
@@ -52,7 +54,7 @@ public class CryptoAutoConfiguration {
 | 
				
			|||||||
    @Bean
 | 
					    @Bean
 | 
				
			||||||
    @ConditionalOnMissingBean
 | 
					    @ConditionalOnMissingBean
 | 
				
			||||||
    public MyBatisEncryptInterceptor myBatisEncryptInterceptor() {
 | 
					    public MyBatisEncryptInterceptor myBatisEncryptInterceptor() {
 | 
				
			||||||
        return new MyBatisEncryptInterceptor(properties);
 | 
					        return new MyBatisEncryptInterceptor();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -61,11 +63,12 @@ public class CryptoAutoConfiguration {
 | 
				
			|||||||
    @Bean
 | 
					    @Bean
 | 
				
			||||||
    @ConditionalOnMissingBean(MyBatisDecryptInterceptor.class)
 | 
					    @ConditionalOnMissingBean(MyBatisDecryptInterceptor.class)
 | 
				
			||||||
    public MyBatisDecryptInterceptor myBatisDecryptInterceptor() {
 | 
					    public MyBatisDecryptInterceptor myBatisDecryptInterceptor() {
 | 
				
			||||||
        return new MyBatisDecryptInterceptor(properties);
 | 
					        return new MyBatisDecryptInterceptor();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostConstruct
 | 
					    @PostConstruct
 | 
				
			||||||
    public void postConstruct() {
 | 
					    public void postConstruct() {
 | 
				
			||||||
 | 
					        EncryptHelper.init(properties);
 | 
				
			||||||
        log.debug("[ContiNew Starter] - Auto Configuration 'Security-Crypto' completed initialization.");
 | 
					        log.debug("[ContiNew Starter] - Auto Configuration 'Security-Crypto' completed initialization.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,11 +18,13 @@ package top.continew.starter.security.crypto.autoconfigure;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
					import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
				
			||||||
import top.continew.starter.core.constant.PropertiesConstants;
 | 
					import top.continew.starter.core.constant.PropertiesConstants;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.enums.Algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 加/解密配置属性
 | 
					 * 加/解密配置属性
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@ConfigurationProperties(PropertiesConstants.SECURITY_CRYPTO)
 | 
					@ConfigurationProperties(PropertiesConstants.SECURITY_CRYPTO)
 | 
				
			||||||
@@ -33,6 +35,11 @@ public class CryptoProperties {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private boolean enabled = true;
 | 
					    private boolean enabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认算法
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private Algorithm algorithm = Algorithm.AES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 对称加密算法密钥
 | 
					     * 对称加密算法密钥
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -56,6 +63,14 @@ public class CryptoProperties {
 | 
				
			|||||||
        this.enabled = enabled;
 | 
					        this.enabled = enabled;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Algorithm getAlgorithm() {
 | 
				
			||||||
 | 
					        return algorithm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setAlgorithm(Algorithm algorithm) {
 | 
				
			||||||
 | 
					        this.algorithm = algorithm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String getPassword() {
 | 
					    public String getPassword() {
 | 
				
			||||||
        return password;
 | 
					        return password;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,14 +18,11 @@ package top.continew.starter.security.crypto.core;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import cn.hutool.core.text.CharSequenceUtil;
 | 
					import cn.hutool.core.text.CharSequenceUtil;
 | 
				
			||||||
import cn.hutool.core.util.ReflectUtil;
 | 
					import cn.hutool.core.util.ReflectUtil;
 | 
				
			||||||
import cn.hutool.extra.spring.SpringUtil;
 | 
					 | 
				
			||||||
import org.apache.ibatis.annotations.Param;
 | 
					import org.apache.ibatis.annotations.Param;
 | 
				
			||||||
import org.apache.ibatis.mapping.MappedStatement;
 | 
					import org.apache.ibatis.mapping.MappedStatement;
 | 
				
			||||||
import top.continew.starter.core.constant.StringConstants;
 | 
					import top.continew.starter.core.constant.StringConstants;
 | 
				
			||||||
import top.continew.starter.core.exception.BaseException;
 | 
					import top.continew.starter.core.exception.BaseException;
 | 
				
			||||||
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
					import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
				
			||||||
import top.continew.starter.security.crypto.encryptor.IEncryptor;
 | 
					 | 
				
			||||||
import top.continew.starter.security.crypto.enums.Algorithm;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Field;
 | 
					import java.lang.reflect.Field;
 | 
				
			||||||
import java.lang.reflect.Method;
 | 
					import java.lang.reflect.Method;
 | 
				
			||||||
@@ -71,23 +68,6 @@ public abstract class AbstractMyBatisInterceptor {
 | 
				
			|||||||
            .toList());
 | 
					            .toList());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 获取字段加/解密处理器
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param fieldEncrypt 字段加密注解
 | 
					 | 
				
			||||||
     * @return 加/解密处理器
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected IEncryptor getEncryptor(FieldEncrypt fieldEncrypt) {
 | 
					 | 
				
			||||||
        Class<? extends IEncryptor> encryptorClass = fieldEncrypt.encryptor();
 | 
					 | 
				
			||||||
        // 使用预定义加/解密处理器
 | 
					 | 
				
			||||||
        if (encryptorClass == IEncryptor.class) {
 | 
					 | 
				
			||||||
            Algorithm algorithm = fieldEncrypt.value();
 | 
					 | 
				
			||||||
            return ReflectUtil.newInstance(algorithm.getEncryptor());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // 使用自定义加/解密处理器
 | 
					 | 
				
			||||||
        return SpringUtil.getBean(encryptorClass);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获取加密参数
 | 
					     * 获取加密参数
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
package top.continew.starter.security.crypto.core;
 | 
					package top.continew.starter.security.crypto.core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.hutool.core.collection.CollUtil;
 | 
					import cn.hutool.core.collection.CollUtil;
 | 
				
			||||||
 | 
					import cn.hutool.core.text.CharSequenceUtil;
 | 
				
			||||||
import cn.hutool.core.util.ObjectUtil;
 | 
					import cn.hutool.core.util.ObjectUtil;
 | 
				
			||||||
import cn.hutool.core.util.ReflectUtil;
 | 
					import cn.hutool.core.util.ReflectUtil;
 | 
				
			||||||
import org.apache.ibatis.executor.resultset.ResultSetHandler;
 | 
					import org.apache.ibatis.executor.resultset.ResultSetHandler;
 | 
				
			||||||
@@ -25,39 +26,30 @@ import org.apache.ibatis.plugin.Intercepts;
 | 
				
			|||||||
import org.apache.ibatis.plugin.Invocation;
 | 
					import org.apache.ibatis.plugin.Invocation;
 | 
				
			||||||
import org.apache.ibatis.plugin.Signature;
 | 
					import org.apache.ibatis.plugin.Signature;
 | 
				
			||||||
import org.apache.ibatis.type.SimpleTypeRegistry;
 | 
					import org.apache.ibatis.type.SimpleTypeRegistry;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					 | 
				
			||||||
import org.slf4j.LoggerFactory;
 | 
					 | 
				
			||||||
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
					import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
				
			||||||
import top.continew.starter.security.crypto.autoconfigure.CryptoProperties;
 | 
					import top.continew.starter.security.crypto.utils.EncryptHelper;
 | 
				
			||||||
import top.continew.starter.security.crypto.encryptor.IEncryptor;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Field;
 | 
					import java.lang.reflect.Field;
 | 
				
			||||||
import java.sql.Statement;
 | 
					import java.sql.Statement;
 | 
				
			||||||
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 字段解密拦截器
 | 
					 * 字段解密拦截器
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
 | 
					@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
 | 
				
			||||||
public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor implements Interceptor {
 | 
					public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor implements Interceptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final Logger log = LoggerFactory.getLogger(MyBatisDecryptInterceptor.class);
 | 
					 | 
				
			||||||
    private CryptoProperties properties;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public MyBatisDecryptInterceptor(CryptoProperties properties) {
 | 
					 | 
				
			||||||
        this.properties = properties;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public MyBatisDecryptInterceptor() {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Object intercept(Invocation invocation) throws Throwable {
 | 
					    public Object intercept(Invocation invocation) throws Throwable {
 | 
				
			||||||
 | 
					        // 获取执行结果
 | 
				
			||||||
        Object obj = invocation.proceed();
 | 
					        Object obj = invocation.proceed();
 | 
				
			||||||
        if (obj == null) {
 | 
					        if (ObjectUtil.isNull(obj)) {
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // 确保目标是 ResultSetHandler
 | 
					        // 确保目标是 ResultSetHandler
 | 
				
			||||||
@@ -68,6 +60,9 @@ public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
        if (obj instanceof List<?> resultList) {
 | 
					        if (obj instanceof List<?> resultList) {
 | 
				
			||||||
            // 处理列表结果
 | 
					            // 处理列表结果
 | 
				
			||||||
            this.decryptList(resultList);
 | 
					            this.decryptList(resultList);
 | 
				
			||||||
 | 
					        } else if (obj instanceof Map<?, ?> map) {
 | 
				
			||||||
 | 
					            // 处理Map结果
 | 
				
			||||||
 | 
					            this.decryptMap(map);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // 处理单个对象结果
 | 
					            // 处理单个对象结果
 | 
				
			||||||
            this.decryptObject(obj);
 | 
					            this.decryptObject(obj);
 | 
				
			||||||
@@ -89,13 +84,25 @@ public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 解密Map结果
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param resultMap 结果Map
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void decryptMap(Map<?, ?> resultMap) {
 | 
				
			||||||
 | 
					        if (CollUtil.isEmpty(resultMap)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        new HashSet<>(resultMap.values()).forEach(this::decryptObject);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 解密单个对象结果
 | 
					     * 解密单个对象结果
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param result 结果对象
 | 
					     * @param result 结果对象
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void decryptObject(Object result) {
 | 
					    private void decryptObject(Object result) {
 | 
				
			||||||
        if (result == null) {
 | 
					        if (ObjectUtil.isNull(result)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // String、Integer、Long 等简单类型对象无需处理
 | 
					        // String、Integer、Long 等简单类型对象无需处理
 | 
				
			||||||
@@ -109,21 +116,16 @@ public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // 解密处理
 | 
					        // 解密处理
 | 
				
			||||||
        for (Field field : fieldList) {
 | 
					        for (Field field : fieldList) {
 | 
				
			||||||
            IEncryptor encryptor = super.getEncryptor(field.getAnnotation(FieldEncrypt.class));
 | 
					 | 
				
			||||||
            Object fieldValue = ReflectUtil.getFieldValue(result, field);
 | 
					            Object fieldValue = ReflectUtil.getFieldValue(result, field);
 | 
				
			||||||
            if (fieldValue == null) {
 | 
					            if (fieldValue == null) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // 优先获取自定义对称加密算法密钥,获取不到时再获取全局配置
 | 
					            String strValue = String.valueOf(fieldValue);
 | 
				
			||||||
            String password = ObjectUtil.defaultIfBlank(field.getAnnotation(FieldEncrypt.class).password(), properties
 | 
					            if (CharSequenceUtil.isBlank(strValue)) {
 | 
				
			||||||
                .getPassword());
 | 
					                continue;
 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                String ciphertext = encryptor.decrypt(fieldValue.toString(), password, properties.getPrivateKey());
 | 
					 | 
				
			||||||
                ReflectUtil.setFieldValue(result, field, ciphertext);
 | 
					 | 
				
			||||||
            } catch (Exception e) {
 | 
					 | 
				
			||||||
                // 解密失败时保留原值,避免影响正常业务流程
 | 
					 | 
				
			||||||
                log.warn("解密失败,请检查加密配置", e);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            ReflectUtil.setFieldValue(result, field, EncryptHelper.decrypt(strValue, field
 | 
				
			||||||
 | 
					                .getAnnotation(FieldEncrypt.class)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -28,12 +28,9 @@ import org.apache.ibatis.mapping.BoundSql;
 | 
				
			|||||||
import org.apache.ibatis.mapping.MappedStatement;
 | 
					import org.apache.ibatis.mapping.MappedStatement;
 | 
				
			||||||
import org.apache.ibatis.session.ResultHandler;
 | 
					import org.apache.ibatis.session.ResultHandler;
 | 
				
			||||||
import org.apache.ibatis.session.RowBounds;
 | 
					import org.apache.ibatis.session.RowBounds;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					 | 
				
			||||||
import org.slf4j.LoggerFactory;
 | 
					 | 
				
			||||||
import top.continew.starter.core.constant.StringConstants;
 | 
					import top.continew.starter.core.constant.StringConstants;
 | 
				
			||||||
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
					import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
				
			||||||
import top.continew.starter.security.crypto.autoconfigure.CryptoProperties;
 | 
					import top.continew.starter.security.crypto.utils.EncryptHelper;
 | 
				
			||||||
import top.continew.starter.security.crypto.encryptor.IEncryptor;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Field;
 | 
					import java.lang.reflect.Field;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
@@ -47,18 +44,13 @@ import java.util.regex.Pattern;
 | 
				
			|||||||
 * 字段加密拦截器
 | 
					 * 字段加密拦截器
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor implements InnerInterceptor {
 | 
					public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor implements InnerInterceptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final Logger log = LoggerFactory.getLogger(MyBatisEncryptInterceptor.class);
 | 
					 | 
				
			||||||
    private static final Pattern PARAM_PAIRS_PATTERN = Pattern
 | 
					    private static final Pattern PARAM_PAIRS_PATTERN = Pattern
 | 
				
			||||||
        .compile("#\\{ew\\.paramNameValuePairs\\.(" + Constants.WRAPPER_PARAM + "\\d+)\\}");
 | 
					        .compile("#\\{ew\\.paramNameValuePairs\\.(" + Constants.WRAPPER_PARAM + "\\d+)\\}");
 | 
				
			||||||
    private final CryptoProperties properties;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public MyBatisEncryptInterceptor(CryptoProperties properties) {
 | 
					 | 
				
			||||||
        this.properties = properties;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void beforeQuery(Executor executor,
 | 
					    public void beforeQuery(Executor executor,
 | 
				
			||||||
@@ -124,22 +116,16 @@ public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private void encryptEntity(List<Field> fieldList, Object entity) {
 | 
					    private void encryptEntity(List<Field> fieldList, Object entity) {
 | 
				
			||||||
        for (Field field : fieldList) {
 | 
					        for (Field field : fieldList) {
 | 
				
			||||||
            IEncryptor encryptor = super.getEncryptor(field.getAnnotation(FieldEncrypt.class));
 | 
					 | 
				
			||||||
            Object fieldValue = ReflectUtil.getFieldValue(entity, field);
 | 
					            Object fieldValue = ReflectUtil.getFieldValue(entity, field);
 | 
				
			||||||
            if (fieldValue == null) {
 | 
					            if (fieldValue == null) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // 优先获取自定义对称加密算法密钥,获取不到时再获取全局配置
 | 
					            String strValue = String.valueOf(fieldValue);
 | 
				
			||||||
            String password = ObjectUtil.defaultIfBlank(field.getAnnotation(FieldEncrypt.class).password(), properties
 | 
					            if (CharSequenceUtil.isBlank(strValue)) {
 | 
				
			||||||
                .getPassword());
 | 
					                continue;
 | 
				
			||||||
            String ciphertext = fieldValue.toString();
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                ciphertext = encryptor.encrypt(fieldValue.toString(), password, properties.getPublicKey());
 | 
					 | 
				
			||||||
            } catch (Exception e) {
 | 
					 | 
				
			||||||
                // 加密失败时保留原值,避免影响正常业务流程
 | 
					 | 
				
			||||||
                log.warn("加密失败,请检查加密配置", e);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ReflectUtil.setFieldValue(entity, field, ciphertext);
 | 
					            ReflectUtil.setFieldValue(entity, field, EncryptHelper.encrypt(strValue, field
 | 
				
			||||||
 | 
					                .getAnnotation(FieldEncrypt.class)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,8 +183,7 @@ public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
                if (matcher.matches()) {
 | 
					                if (matcher.matches()) {
 | 
				
			||||||
                    String valueKey = matcher.group(1);
 | 
					                    String valueKey = matcher.group(1);
 | 
				
			||||||
                    Object value = updateWrapper.getParamNameValuePairs().get(valueKey);
 | 
					                    Object value = updateWrapper.getParamNameValuePairs().get(valueKey);
 | 
				
			||||||
                    Object ciphertext = this.doEncrypt(value, fieldEncrypt);
 | 
					                    updateWrapper.getParamNameValuePairs().put(valueKey, this.doEncrypt(value, fieldEncrypt));
 | 
				
			||||||
                    updateWrapper.getParamNameValuePairs().put(valueKey, ciphertext);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -211,19 +196,14 @@ public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor implem
 | 
				
			|||||||
     * @param fieldEncrypt   字段加密注解
 | 
					     * @param fieldEncrypt   字段加密注解
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private Object doEncrypt(Object parameterValue, FieldEncrypt fieldEncrypt) {
 | 
					    private Object doEncrypt(Object parameterValue, FieldEncrypt fieldEncrypt) {
 | 
				
			||||||
        if (parameterValue == null) {
 | 
					        if (ObjectUtil.isNull(parameterValue)) {
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        IEncryptor encryptor = super.getEncryptor(fieldEncrypt);
 | 
					        String strValue = String.valueOf(parameterValue);
 | 
				
			||||||
        // 优先获取自定义对称加密算法密钥,获取不到时再获取全局配置
 | 
					        if (CharSequenceUtil.isBlank(strValue)) {
 | 
				
			||||||
        String password = ObjectUtil.defaultIfBlank(fieldEncrypt.password(), properties.getPassword());
 | 
					            return null;
 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            return encryptor.encrypt(parameterValue.toString(), password, properties.getPublicKey());
 | 
					 | 
				
			||||||
        } catch (Exception e) {
 | 
					 | 
				
			||||||
            // 加密失败时保留原值,避免影响正常业务流程
 | 
					 | 
				
			||||||
            log.warn("加密失败,请检查加密配置", e);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return parameterValue;
 | 
					        return EncryptHelper.encrypt(strValue, fieldEncrypt);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					 * <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 top.continew.starter.security.crypto.encryptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 加密器基类
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public abstract class AbstractEncryptor implements IEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public AbstractEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        // 配置校验与配置注入
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -29,26 +29,40 @@ import java.util.concurrent.ConcurrentHashMap;
 | 
				
			|||||||
 * 对称加/解密处理器
 | 
					 * 对称加/解密处理器
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public abstract class AbstractSymmetricCryptoEncryptor implements IEncryptor {
 | 
					public abstract class AbstractSymmetricCryptoEncryptor extends AbstractEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 对称加密缓存
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private static final Map<String, SymmetricCrypto> CACHE = new ConcurrentHashMap<>();
 | 
					    private static final Map<String, SymmetricCrypto> CACHE = new ConcurrentHashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    /**
 | 
				
			||||||
    public String encrypt(String plaintext, String password, String publicKey) throws Exception {
 | 
					     * 加密上下文
 | 
				
			||||||
        if (CharSequenceUtil.isBlank(plaintext)) {
 | 
					     */
 | 
				
			||||||
            return plaintext;
 | 
					    private final CryptoContext context;
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        return this.getCrypto(password).encryptHex(plaintext);
 | 
					    public AbstractSymmetricCryptoEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        super(context);
 | 
				
			||||||
 | 
					        this.context = context;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String decrypt(String ciphertext, String password, String privateKey) throws Exception {
 | 
					    public String encrypt(String plaintext) {
 | 
				
			||||||
 | 
					        if (CharSequenceUtil.isBlank(plaintext)) {
 | 
				
			||||||
 | 
					            return plaintext;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this.getCrypto(context.getPassword()).encryptHex(plaintext);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String decrypt(String ciphertext) {
 | 
				
			||||||
        if (CharSequenceUtil.isBlank(ciphertext)) {
 | 
					        if (CharSequenceUtil.isBlank(ciphertext)) {
 | 
				
			||||||
            return ciphertext;
 | 
					            return ciphertext;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return this.getCrypto(password).decryptStr(ciphertext);
 | 
					        return this.getCrypto(context.getPassword()).decryptStr(ciphertext);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,10 @@ import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class AesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
					public class AesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public AesEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        super(context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected SymmetricAlgorithm getAlgorithm() {
 | 
					    protected SymmetricAlgorithm getAlgorithm() {
 | 
				
			||||||
        return SymmetricAlgorithm.AES;
 | 
					        return SymmetricAlgorithm.AES;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,12 +30,12 @@ import cn.hutool.core.codec.Base64;
 | 
				
			|||||||
public class Base64Encryptor implements IEncryptor {
 | 
					public class Base64Encryptor implements IEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String encrypt(String plaintext, String password, String publicKey) throws Exception {
 | 
					    public String encrypt(String plaintext) {
 | 
				
			||||||
        return Base64.encode(plaintext);
 | 
					        return Base64.encode(plaintext);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String decrypt(String ciphertext, String password, String privateKey) throws Exception {
 | 
					    public String decrypt(String ciphertext) {
 | 
				
			||||||
        return Base64.decodeStr(ciphertext);
 | 
					        return Base64.decodeStr(ciphertext);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					 * <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 top.continew.starter.security.crypto.encryptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.enums.Algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Objects;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 加密上下文
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class CryptoContext {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认算法
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private Algorithm algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 对称加密算法密钥
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private String password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 非对称加密算法公钥
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private String publicKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 非对称加密算法私钥
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private String privateKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Algorithm getAlgorithm() {
 | 
				
			||||||
 | 
					        return algorithm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setAlgorithm(Algorithm algorithm) {
 | 
				
			||||||
 | 
					        this.algorithm = algorithm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getPassword() {
 | 
				
			||||||
 | 
					        return password;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setPassword(String password) {
 | 
				
			||||||
 | 
					        this.password = password;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getPublicKey() {
 | 
				
			||||||
 | 
					        return publicKey;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setPublicKey(String publicKey) {
 | 
				
			||||||
 | 
					        this.publicKey = publicKey;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getPrivateKey() {
 | 
				
			||||||
 | 
					        return privateKey;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setPrivateKey(String privateKey) {
 | 
				
			||||||
 | 
					        this.privateKey = privateKey;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean equals(Object o) {
 | 
				
			||||||
 | 
					        if (this == o) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (o == null || getClass() != o.getClass()) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        CryptoContext that = (CryptoContext)o;
 | 
				
			||||||
 | 
					        return algorithm == that.algorithm && Objects.equals(password, that.password) && Objects
 | 
				
			||||||
 | 
					            .equals(publicKey, that.publicKey) && Objects.equals(privateKey, that.privateKey);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int hashCode() {
 | 
				
			||||||
 | 
					        return Objects.hash(algorithm, password, publicKey, privateKey);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -29,6 +29,10 @@ import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class DesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
					public class DesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public DesEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        super(context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected SymmetricAlgorithm getAlgorithm() {
 | 
					    protected SymmetricAlgorithm getAlgorithm() {
 | 
				
			||||||
        return SymmetricAlgorithm.DES;
 | 
					        return SymmetricAlgorithm.DES;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ package top.continew.starter.security.crypto.encryptor;
 | 
				
			|||||||
 * 加/解密接口
 | 
					 * 加/解密接口
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public interface IEncryptor {
 | 
					public interface IEncryptor {
 | 
				
			||||||
@@ -28,21 +29,15 @@ public interface IEncryptor {
 | 
				
			|||||||
     * 加密
 | 
					     * 加密
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param plaintext 明文
 | 
					     * @param plaintext 明文
 | 
				
			||||||
     * @param password  对称加密算法密钥
 | 
					 | 
				
			||||||
     * @param publicKey 非对称加密算法公钥
 | 
					 | 
				
			||||||
     * @return 加密后的文本
 | 
					     * @return 加密后的文本
 | 
				
			||||||
     * @throws Exception /
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    String encrypt(String plaintext, String password, String publicKey) throws Exception;
 | 
					    String encrypt(String plaintext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 解密
 | 
					     * 解密
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param ciphertext 密文
 | 
					     * @param ciphertext 密文
 | 
				
			||||||
     * @param password   对称加密算法密钥
 | 
					 | 
				
			||||||
     * @param privateKey 非对称加密算法私钥
 | 
					 | 
				
			||||||
     * @return 解密后的文本
 | 
					     * @return 解密后的文本
 | 
				
			||||||
     * @throws Exception /
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    String decrypt(String ciphertext, String password, String privateKey) throws Exception;
 | 
					    String decrypt(String ciphertext);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,10 @@ import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class PbeWithMd5AndDesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
					public class PbeWithMd5AndDesEncryptor extends AbstractSymmetricCryptoEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public PbeWithMd5AndDesEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        super(context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected SymmetricAlgorithm getAlgorithm() {
 | 
					    protected SymmetricAlgorithm getAlgorithm() {
 | 
				
			||||||
        return SymmetricAlgorithm.PBEWithMD5AndDES;
 | 
					        return SymmetricAlgorithm.PBEWithMD5AndDES;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,17 +27,29 @@ import cn.hutool.crypto.asymmetric.KeyType;
 | 
				
			|||||||
 * </p>
 | 
					 * </p>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class RsaEncryptor implements IEncryptor {
 | 
					public class RsaEncryptor extends AbstractEncryptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    /**
 | 
				
			||||||
    public String encrypt(String plaintext, String password, String publicKey) throws Exception {
 | 
					     * 加密上下文
 | 
				
			||||||
        return Base64.encode(SecureUtil.rsa(null, publicKey).encrypt(plaintext, KeyType.PublicKey));
 | 
					     */
 | 
				
			||||||
 | 
					    private final CryptoContext context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public RsaEncryptor(CryptoContext context) {
 | 
				
			||||||
 | 
					        super(context);
 | 
				
			||||||
 | 
					        this.context = context;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String decrypt(String ciphertext, String password, String privateKey) throws Exception {
 | 
					    public String encrypt(String plaintext) {
 | 
				
			||||||
        return new String(SecureUtil.rsa(privateKey, null).decrypt(Base64.decode(ciphertext), KeyType.PrivateKey));
 | 
					        return Base64.encode(SecureUtil.rsa(null, context.getPublicKey()).encrypt(plaintext, KeyType.PublicKey));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String decrypt(String ciphertext) {
 | 
				
			||||||
 | 
					        return new String(SecureUtil.rsa(context.getPrivateKey(), null)
 | 
				
			||||||
 | 
					            .decrypt(Base64.decode(ciphertext), KeyType.PrivateKey));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,16 @@ import top.continew.starter.security.crypto.encryptor.*;
 | 
				
			|||||||
 * 加密/解密算法枚举
 | 
					 * 加密/解密算法枚举
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 * @since 1.4.0
 | 
					 * @since 1.4.0
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public enum Algorithm {
 | 
					public enum Algorithm {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认使用配置属性的算法
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    DEFAULT(null),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * AES
 | 
					     * AES
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
				
			||||||
 | 
					 * <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 top.continew.starter.security.crypto.utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.hutool.core.text.CharSequenceUtil;
 | 
				
			||||||
 | 
					import cn.hutool.core.util.ReflectUtil;
 | 
				
			||||||
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.annotation.FieldEncrypt;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.autoconfigure.CryptoProperties;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.encryptor.CryptoContext;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.encryptor.IEncryptor;
 | 
				
			||||||
 | 
					import top.continew.starter.security.crypto.enums.Algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.lang.reflect.Field;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 加密助手
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author lishuyan
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class EncryptHelper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final Logger log = LoggerFactory.getLogger(EncryptHelper.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 默认加密配置
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static CryptoProperties defaultProperties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 加密器缓存
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static final Map<Integer, IEncryptor> ENCRYPTOR_CACHE = new ConcurrentHashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 初始化默认配置
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param properties 加密配置
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static void init(CryptoProperties properties) {
 | 
				
			||||||
 | 
					        defaultProperties = properties;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 注册加密执行者到缓存
 | 
				
			||||||
 | 
					     * <p>
 | 
				
			||||||
 | 
					     * 计算 CryptoContext 对象的hashCode作为缓存中的key,通过hashCode查询缓存中存在则直接返回,不存在则创建并缓存
 | 
				
			||||||
 | 
					     * </p>
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param encryptContext 加密执行者需要的相关配置参数
 | 
				
			||||||
 | 
					     * @return 加密执行者
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static IEncryptor registerAndGetEncryptor(CryptoContext encryptContext) {
 | 
				
			||||||
 | 
					        int key = encryptContext.hashCode();
 | 
				
			||||||
 | 
					        return ENCRYPTOR_CACHE.computeIfAbsent(key, k -> ReflectUtil.newInstance(encryptContext.getAlgorithm()
 | 
				
			||||||
 | 
					            .getEncryptor(), encryptContext));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 获取字段上的 @FieldEncrypt 注解
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param obj       对象
 | 
				
			||||||
 | 
					     * @param fieldName 字段名称
 | 
				
			||||||
 | 
					     * @return 字段上的 @FieldEncrypt 注解
 | 
				
			||||||
 | 
					     * @throws NoSuchFieldException /
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static FieldEncrypt getFieldEncrypt(Object obj, String fieldName) throws NoSuchFieldException {
 | 
				
			||||||
 | 
					        Field field = obj.getClass().getDeclaredField(fieldName);
 | 
				
			||||||
 | 
					        return field.getAnnotation(FieldEncrypt.class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 加密方法
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value        待加密字符串
 | 
				
			||||||
 | 
					     * @param fieldEncrypt 待加密字段注解
 | 
				
			||||||
 | 
					     * @return 加密后的字符串
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String encrypt(String value, FieldEncrypt fieldEncrypt) {
 | 
				
			||||||
 | 
					        if (CharSequenceUtil.isBlank(value) || fieldEncrypt == null || !defaultProperties.isEnabled()) {
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String ciphertext = value;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CryptoContext encryptContext = buildEncryptContext(fieldEncrypt);
 | 
				
			||||||
 | 
					            IEncryptor encryptor = registerAndGetEncryptor(encryptContext);
 | 
				
			||||||
 | 
					            ciphertext = encryptor.encrypt(ciphertext);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            log.warn("加密失败,请检查加密配置,处理加密字段异常:{}", e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ciphertext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 加密方法
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value 待加密字符串
 | 
				
			||||||
 | 
					     * @return 加密后的字符串
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String encrypt(String value) {
 | 
				
			||||||
 | 
					        if (CharSequenceUtil.isBlank(value) || !defaultProperties.isEnabled()) {
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String ciphertext = value;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CryptoContext encryptContext = buildEncryptContext();
 | 
				
			||||||
 | 
					            IEncryptor encryptor = registerAndGetEncryptor(encryptContext);
 | 
				
			||||||
 | 
					            ciphertext = encryptor.encrypt(ciphertext);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            log.warn("加密失败,请检查加密配置,处理加密字段异常:{}", e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return ciphertext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 解密方法
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value        待解密字符串
 | 
				
			||||||
 | 
					     * @param fieldEncrypt 待解密字段注解
 | 
				
			||||||
 | 
					     * @return 解密后的字符串
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String decrypt(String value, FieldEncrypt fieldEncrypt) {
 | 
				
			||||||
 | 
					        if (CharSequenceUtil.isBlank(value) || fieldEncrypt == null || !defaultProperties.isEnabled()) {
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String plaintext = value;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CryptoContext encryptContext = buildEncryptContext(fieldEncrypt);
 | 
				
			||||||
 | 
					            IEncryptor encryptor = registerAndGetEncryptor(encryptContext);
 | 
				
			||||||
 | 
					            plaintext = encryptor.decrypt(plaintext);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            log.warn("解密失败,请检查加密配置,处理解密字段异常:{}", e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return plaintext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 解密方法
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value 待解密字符串
 | 
				
			||||||
 | 
					     * @return 解密后的字符串
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static String decrypt(String value) {
 | 
				
			||||||
 | 
					        if (CharSequenceUtil.isBlank(value) || !defaultProperties.isEnabled()) {
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        String plaintext = value;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            CryptoContext encryptContext = buildEncryptContext();
 | 
				
			||||||
 | 
					            IEncryptor encryptor = registerAndGetEncryptor(encryptContext);
 | 
				
			||||||
 | 
					            plaintext = encryptor.decrypt(plaintext);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            log.warn("解密失败,请检查加密配置,处理解密字段异常:{}", e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return plaintext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建加密上下文
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param fieldEncrypt 字段加密注解
 | 
				
			||||||
 | 
					     * @return 加密上下文
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static CryptoContext buildEncryptContext(FieldEncrypt fieldEncrypt) {
 | 
				
			||||||
 | 
					        CryptoContext encryptContext = new CryptoContext();
 | 
				
			||||||
 | 
					        encryptContext.setAlgorithm(fieldEncrypt.value() == Algorithm.DEFAULT
 | 
				
			||||||
 | 
					            ? defaultProperties.getAlgorithm()
 | 
				
			||||||
 | 
					            : fieldEncrypt.value());
 | 
				
			||||||
 | 
					        encryptContext.setPassword(fieldEncrypt.password().isEmpty()
 | 
				
			||||||
 | 
					            ? defaultProperties.getPassword()
 | 
				
			||||||
 | 
					            : fieldEncrypt.password());
 | 
				
			||||||
 | 
					        encryptContext.setPrivateKey(fieldEncrypt.privateKey().isEmpty()
 | 
				
			||||||
 | 
					            ? defaultProperties.getPrivateKey()
 | 
				
			||||||
 | 
					            : fieldEncrypt.privateKey());
 | 
				
			||||||
 | 
					        encryptContext.setPublicKey(fieldEncrypt.publicKey().isEmpty()
 | 
				
			||||||
 | 
					            ? defaultProperties.getPublicKey()
 | 
				
			||||||
 | 
					            : fieldEncrypt.publicKey());
 | 
				
			||||||
 | 
					        return encryptContext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 构建加密上下文
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return 加密上下文
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static CryptoContext buildEncryptContext() {
 | 
				
			||||||
 | 
					        CryptoContext encryptContext = new CryptoContext();
 | 
				
			||||||
 | 
					        encryptContext.setAlgorithm(defaultProperties.getAlgorithm());
 | 
				
			||||||
 | 
					        encryptContext.setPassword(defaultProperties.getPassword());
 | 
				
			||||||
 | 
					        encryptContext.setPrivateKey(defaultProperties.getPrivateKey());
 | 
				
			||||||
 | 
					        encryptContext.setPublicKey(defaultProperties.getPublicKey());
 | 
				
			||||||
 | 
					        return encryptContext;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user