mirror of https://gitee.com/stylefeng/roses
新增数据库字段加解密模块
parent
485a01cdec
commit
25fab57768
|
@ -23,6 +23,7 @@
|
||||||
<module>security-sdk-count</module>
|
<module>security-sdk-count</module>
|
||||||
<module>security-sdk-xss</module>
|
<module>security-sdk-xss</module>
|
||||||
<module>security-sdk-request-encrypt-and-decode</module>
|
<module>security-sdk-request-encrypt-and-decode</module>
|
||||||
|
<module>security-sdk-database-field</module>
|
||||||
<module>security-spring-boot-starter</module>
|
<module>security-spring-boot-starter</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|
|
@ -67,4 +67,15 @@ public class SecurityConfigExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取AES秘钥
|
||||||
|
*
|
||||||
|
* @return {@link String}
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 10:15
|
||||||
|
**/
|
||||||
|
public static String getEncryptSecretKey() {
|
||||||
|
return ConfigContext.me().getSysConfigValueWithDefault("SYS_ENCRYPT_SECRET_KEY", String.class, "Ux1dqQ22KxVjSYootgzMe776em8vWEGE");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
数据库字段加解密工具
|
||||||
|
|
||||||
|
注意:
|
||||||
|
|
||||||
|
1.数据库加密字段的类型为String类型
|
||||||
|
|
||||||
|
2.如果开启功能时数据库对应字段已经有数据,需要对旧数据进行处理,可以通过EncryptAlgorithmApi对字段进行加密
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
1.通过mybatis的拦截器,对传入参数和返回结果进行处理
|
||||||
|
|
||||||
|
2.可以满足对某个数据库字段在入库时加密,在查询时解密的需求
|
||||||
|
|
||||||
|
3.同时也满足对某个数据库字段在入库时加密,查询时依旧显示密文,只有在需要的时候解密的需求
|
||||||
|
|
||||||
|
使用方法:
|
||||||
|
|
||||||
|
1.给类添加ProtectedData注解,以标识该类需要进行加解密处理
|
||||||
|
|
||||||
|
2.在需要加解密的字段上面添加ProtectedField注解,即可实现在入库时加密,查询时解密的功能
|
||||||
|
|
||||||
|
3.如果不想在查询时解密,则在字段上添加EncryptField注解替换ProtectedField注解,即可实现在入库时该字段加密,查询时不解密的功能
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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>cn.stylefeng.roses</groupId>
|
||||||
|
<artifactId>kernel-d-security</artifactId>
|
||||||
|
<version>7.0.4</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>security-sdk-database-field</artifactId>
|
||||||
|
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!--安全模块的api-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
|
<artifactId>security-api</artifactId>
|
||||||
|
<version>${roses.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--scanner api-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
|
<artifactId>scanner-api</artifactId>
|
||||||
|
<version>${roses.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--web模块-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--数据库的依赖,主要依赖mybatis-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
|
<artifactId>db-api</artifactId>
|
||||||
|
<version>${roses.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,32 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.algorithm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密算法接口
|
||||||
|
* <p>
|
||||||
|
* 可根据自身需要自定义实现,默认实现为AES
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:02
|
||||||
|
*/
|
||||||
|
public interface EncryptAlgorithmApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密算法
|
||||||
|
*
|
||||||
|
* @param encryptedData 加密数据
|
||||||
|
* @return {@link java.lang.String}
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:07
|
||||||
|
**/
|
||||||
|
String encrypt(String encryptedData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密算法
|
||||||
|
*
|
||||||
|
* @param cipher 待解密密文
|
||||||
|
* @return {@link java.lang.String}
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:33
|
||||||
|
**/
|
||||||
|
String decrypt(String cipher);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.algorithm.impl;
|
||||||
|
|
||||||
|
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
||||||
|
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 加密解密实现
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:43
|
||||||
|
*/
|
||||||
|
public class AesEncryptAlgorithmApiImpl implements EncryptAlgorithmApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES加密实体类
|
||||||
|
*/
|
||||||
|
public final SymmetricCrypto symmetricCrypto;
|
||||||
|
|
||||||
|
public AesEncryptAlgorithmApiImpl(byte[] key) {
|
||||||
|
symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encrypt(String encryptedData) {
|
||||||
|
return symmetricCrypto.encryptHex(encryptedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String decrypt(String cipher) {
|
||||||
|
return symmetricCrypto.decryptStr(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要加密字段注解
|
||||||
|
* <p>
|
||||||
|
* 该注解作用范围在字段上面(该类需要加 {@link ProtectedData} 注解)
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 10:57
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface EncryptField {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被保护数据标识注解(标识那个DTO需要加解密)
|
||||||
|
* <p>
|
||||||
|
* 该注解作用范围在类上面
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 10:54
|
||||||
|
*/
|
||||||
|
@Inherited
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ProtectedData {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要加解密字段注解(该字段自动加解密,数据库是密文,查看时是明文)
|
||||||
|
* <p>
|
||||||
|
* 该注解作用范围在字段上面(该类需要加 {@link ProtectedData} 注解)
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 9:18
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ProtectedField {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.interceptor;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.annotation.EncryptField;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedData;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedField;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.ibatis.executor.parameter.ParameterHandler;
|
||||||
|
import org.apache.ibatis.plugin.*;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mybatis拦截器,拦截入库参数
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:58
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),})
|
||||||
|
public class ParameterInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EncryptAlgorithmApi encryptAlgorithmApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object intercept(Invocation invocation) throws Throwable {
|
||||||
|
|
||||||
|
// 若指定ResultSetHandler ,这里则能强转为ResultSetHandler
|
||||||
|
ParameterHandler parameterHandler = (ParameterHandler)invocation.getTarget();
|
||||||
|
|
||||||
|
// 获取参数对像,即 mapper 中 paramsType 的实例
|
||||||
|
Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject");
|
||||||
|
parameterField.setAccessible(true);
|
||||||
|
|
||||||
|
// 取出实例
|
||||||
|
Object parameterObject = parameterField.get(parameterHandler);
|
||||||
|
if (parameterObject != null) {
|
||||||
|
Class<?> parameterObjectClass = parameterObject.getClass();
|
||||||
|
|
||||||
|
// 校验该实例的类是否被@ProtectedData所注解
|
||||||
|
ProtectedData protectedData = AnnotationUtils.findAnnotation(parameterObjectClass, ProtectedData.class);
|
||||||
|
if (ObjectUtil.isNotNull(protectedData)) {
|
||||||
|
|
||||||
|
//取出当前当前类所有字段
|
||||||
|
Field[] declaredFields = parameterObjectClass.getDeclaredFields();
|
||||||
|
|
||||||
|
// 处理需要加密的字段
|
||||||
|
for (Field declaredField : declaredFields) {
|
||||||
|
|
||||||
|
// 包含其中任意一个即可
|
||||||
|
ProtectedField protectedField = declaredField.getAnnotation(ProtectedField.class);
|
||||||
|
EncryptField encryptField = declaredField.getAnnotation(EncryptField.class);
|
||||||
|
if (ObjectUtil.isNotNull(protectedField) || ObjectUtil.isNotNull(encryptField)) {
|
||||||
|
declaredField.setAccessible(true);
|
||||||
|
Object fieldData = declaredField.get(parameterObject);
|
||||||
|
// 如果是String就处理
|
||||||
|
if (fieldData instanceof String) {
|
||||||
|
String value = (String)fieldData;
|
||||||
|
try {
|
||||||
|
String encrypt = encryptAlgorithmApi.encrypt(value);
|
||||||
|
declaredField.set(parameterObject, encrypt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invocation.proceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object plugin(Object target) {
|
||||||
|
return Plugin.wrap(target, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Properties properties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
package cn.stylefeng.roses.kernel.security.database.interceptor;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedData;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.annotation.ProtectedField;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.ibatis.executor.resultset.ResultSetHandler;
|
||||||
|
import org.apache.ibatis.plugin.*;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mybatis拦截器,拦截返回参数
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/3 11:58
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
|
||||||
|
public class ResultInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EncryptAlgorithmApi encryptAlgorithmApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object intercept(Invocation invocation) throws Throwable {
|
||||||
|
|
||||||
|
//取出查询的结果
|
||||||
|
Object resultObject = invocation.proceed();
|
||||||
|
if (Objects.isNull(resultObject)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断结果是List还是对象
|
||||||
|
if (resultObject instanceof List) {
|
||||||
|
List resultList = (List)resultObject;
|
||||||
|
// 判断是否为空
|
||||||
|
if (ObjectUtil.isNotNull(resultList)) {
|
||||||
|
// 处理数据
|
||||||
|
for (Object result : resultList) {
|
||||||
|
// 对象处理
|
||||||
|
this.objectProcessing(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 处理单个对象
|
||||||
|
this.objectProcessing(resultObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象处理
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 9:52
|
||||||
|
**/
|
||||||
|
private void objectProcessing(Object result) throws IllegalAccessException {
|
||||||
|
Class<?> resultClass = result.getClass();
|
||||||
|
// 是否加注解了
|
||||||
|
ProtectedData annotation = AnnotationUtils.findAnnotation(resultClass, ProtectedData.class);
|
||||||
|
|
||||||
|
// 加注解就去处理
|
||||||
|
if (ObjectUtil.isNotNull(annotation)) {
|
||||||
|
Field[] declaredFields = resultClass.getDeclaredFields();
|
||||||
|
for (Field field : declaredFields) {
|
||||||
|
// 处理字段
|
||||||
|
this.fieldProcessing(result, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param result
|
||||||
|
* @param field
|
||||||
|
* @return
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 9:52
|
||||||
|
**/
|
||||||
|
private void fieldProcessing(Object result, Field field) throws IllegalAccessException {
|
||||||
|
if (this.isTag(field)) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object object = field.get(result);
|
||||||
|
//String的解密
|
||||||
|
if (object instanceof String) {
|
||||||
|
String value = (String)object;
|
||||||
|
//对注解的字段进行逐一解密
|
||||||
|
try {
|
||||||
|
String decrypt = encryptAlgorithmApi.decrypt(value);
|
||||||
|
field.set(result, decrypt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否注解标记了
|
||||||
|
*
|
||||||
|
* @param field 被判断字段
|
||||||
|
* @return {@link boolean}
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 9:35
|
||||||
|
**/
|
||||||
|
private boolean isTag(Field field) {
|
||||||
|
// 包含其中任意一个即可
|
||||||
|
ProtectedField protectedField = field.getAnnotation(ProtectedField.class);
|
||||||
|
if (ObjectUtil.isNotNull(protectedField)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object plugin(Object target) {
|
||||||
|
return Plugin.wrap(target, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Properties properties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,13 @@
|
||||||
<version>${roses.version}</version>
|
<version>${roses.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!--数据库加密解密模块-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
|
<artifactId>security-sdk-database-field</artifactId>
|
||||||
|
<version>${roses.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--CORS过滤器,默认不开启-->
|
<!--CORS过滤器,默认不开启-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.stylefeng.roses</groupId>
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright [2020-2030] [https://www.stylefeng.cn]
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||||
|
*
|
||||||
|
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||||
|
* 2.请不要删除和修改Guns源码头部的版权声明。
|
||||||
|
* 3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||||
|
* 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns
|
||||||
|
* 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns
|
||||||
|
* 6.若您的项目无法满足以上几点,可申请商业授权
|
||||||
|
*/
|
||||||
|
package cn.stylefeng.roses.kernel.security.starter;
|
||||||
|
|
||||||
|
import cn.stylefeng.roses.kernel.security.api.expander.SecurityConfigExpander;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi;
|
||||||
|
import cn.stylefeng.roses.kernel.security.database.algorithm.impl.AesEncryptAlgorithmApiImpl;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密算法自动配置
|
||||||
|
*
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 10:06
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class EncryptAlgorithmAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库加密算法
|
||||||
|
*
|
||||||
|
* @return {@link cn.stylefeng.roses.kernel.security.database.algorithm.EncryptAlgorithmApi}
|
||||||
|
* @author majianguo
|
||||||
|
* @date 2021/7/5 10:16
|
||||||
|
**/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(EncryptAlgorithmApi.class)
|
||||||
|
public EncryptAlgorithmApi encryptAlgorithmApi() {
|
||||||
|
String encryptSecretKey = SecurityConfigExpander.getEncryptSecretKey();
|
||||||
|
return new AesEncryptAlgorithmApiImpl(encryptSecretKey.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue