修改如下:

1.深拷贝修改为set形式
2.加密执行者从基类继承,强制构造方法带参数
This commit is contained in:
mayuanfei 2023-01-17 17:31:15 +08:00
parent 3969ccff8c
commit f688f1570e
9 changed files with 97 additions and 116 deletions

View File

@ -1,6 +1,7 @@
package com.ruoyi.common.encrypt; package com.ruoyi.common.encrypt;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
import lombok.Builder;
import lombok.Data; import lombok.Data;
/** /**
@ -11,6 +12,7 @@ import lombok.Data;
* @date 2023-01-17 08:31 * @date 2023-01-17 08:31
*/ */
@Data @Data
@Builder
public class EncryptContext { public class EncryptContext {
/** /**
* 安全秘钥 * 安全秘钥

View File

@ -20,16 +20,6 @@ public interface IEncryptor {
*/ */
AlgorithmType algorithm(); AlgorithmType algorithm();
/**
* 初始化加密者
*
* @param context 加密上下文
* @throws Exception 抛出异常
* @author 老马
* @date 2023/1/17 09:01
*/
void init(EncryptContext context) throws Exception;
/** /**
* 加密 * 加密
* *

View File

@ -1,11 +1,12 @@
package com.ruoyi.framework.encrypt; package com.ruoyi.framework.encrypt;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.properties.EncryptorProperties; import com.ruoyi.framework.config.properties.EncryptorProperties;
import jodd.util.ClassLoaderUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Map; import java.util.Map;
@ -38,13 +39,22 @@ public class EncryptorManager {
if (encryptorMap.containsKey(encryptorKey)) { if (encryptorMap.containsKey(encryptorKey)) {
return encryptorMap.get(encryptorKey); return encryptorMap.get(encryptorKey);
} }
EncryptContext encryptContext = BeanCopyUtils.copy(properties, EncryptContext.class); EncryptContext encryptContext = EncryptContext.builder()
IEncryptor encryptor = ReflectUtil.newInstance(properties.getAlgorithm().getClazz()); .password(properties.getPassword())
.privateKey(properties.getPrivateKey())
.publicKey(properties.getPublicKey())
.encode(properties.getEncode())
.build();
Class<IEncryptor> clazz = null;
try { try {
encryptor.init(encryptContext); clazz = ClassLoaderUtil.loadClass(properties.getAlgorithm().getClazz());
} catch (Exception e) { } catch (ClassNotFoundException e) {
log.error("加密执行者注册失败。", e); log.error("没有找到配置中指定的加密执行者", e);
} }
if(ObjectUtil.isNull(clazz)) {
return null;
}
IEncryptor encryptor = ReflectUtil.newInstance(clazz, encryptContext);
encryptorMap.put(encryptorKey, encryptor); encryptorMap.put(encryptorKey, encryptor);
return encryptorMap.get(encryptorKey); return encryptorMap.get(encryptorKey);
} }
@ -72,6 +82,9 @@ public class EncryptorManager {
public String encrypt(String value, EncryptorProperties properties) { public String encrypt(String value, EncryptorProperties properties) {
try { try {
IEncryptor encryptor = this.registAndGetEncryptor(properties); IEncryptor encryptor = this.registAndGetEncryptor(properties);
if(ObjectUtil.isNull(encryptor)){
return value;
}
return encryptor.encrypt(value, properties.getEncode()); return encryptor.encrypt(value, properties.getEncode());
} catch (Exception e) { } catch (Exception e) {
log.error("字段加密异常,原样返回", e); log.error("字段加密异常,原样返回", e);
@ -91,6 +104,9 @@ public class EncryptorManager {
public String decrypt(String value, EncryptorProperties properties) { public String decrypt(String value, EncryptorProperties properties) {
try { try {
IEncryptor encryptor = this.registAndGetEncryptor(properties); IEncryptor encryptor = this.registAndGetEncryptor(properties);
if(ObjectUtil.isNull(encryptor)){
return value;
}
return encryptor.decrypt(value, properties.getEncode()); return encryptor.decrypt(value, properties.getEncode());
} catch (Exception e) { } catch (Exception e) {
log.error("字段解密异常,原样返回", e); log.error("字段解密异常,原样返回", e);

View File

@ -0,0 +1,16 @@
package com.ruoyi.framework.encrypt.encryptor;
import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
/**
* 所有加密执行者的基类
*
* @author 老马
* @date 2023-01-17 16:52
*/
public abstract class AbstractEncryptor implements IEncryptor {
public AbstractEncryptor(EncryptContext context) throws Exception{
//子类必须实现带参数的构造方法
}
}

View File

@ -6,7 +6,6 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES; import cn.hutool.crypto.symmetric.AES;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.AlgorithmType;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
@ -18,10 +17,24 @@ import java.nio.charset.StandardCharsets;
* @author 老马 * @author 老马
* @date 2023-01-06 11:39 * @date 2023-01-06 11:39
*/ */
public class AesEncryptor implements IEncryptor { public class AesEncryptor extends AbstractEncryptor {
private AES aes = null; private AES aes = null;
public AesEncryptor(EncryptContext context) throws Exception{
super(context);
String password = context.getPassword();
if (StrUtil.isBlank(password)) {
throw new RuntimeException("aes没有获得秘钥信息");
}
// aes算法的秘钥要求是16位24位32位
int[] array = {16, 24, 32};
if(!ArrayUtil.contains(array, password.length())) {
throw new RuntimeException("aes秘钥长度应该为16位、24位、32位实际为"+password.length()+"");
}
aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
}
/** /**
* 获得当前算法 * 获得当前算法
* *
@ -34,27 +47,6 @@ public class AesEncryptor implements IEncryptor {
return AlgorithmType.AES; return AlgorithmType.AES;
} }
/**
* 初始化加密者
*
* @param context 加密上下文
* @author 老马
* @date 2023/1/17 09:01
*/
@Override
public void init(EncryptContext context) throws Exception {
String password = context.getPassword();
if (StrUtil.isBlank(password)) {
throw new RuntimeException("aes没有获得秘钥信息");
}
// aes算法的秘钥要求是16位24位32位
int[] array = {16, 24, 32};
if(!ArrayUtil.contains(array, password.length())) {
throw new RuntimeException("aes秘钥长度应该为16位、24位、32位实际为"+password.length()+"");
}
aes = SecureUtil.aes(context.getPassword().getBytes(StandardCharsets.UTF_8));
}
/** /**
* 加密 * 加密
* *

View File

@ -2,7 +2,6 @@ package com.ruoyi.framework.encrypt.encryptor;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.AlgorithmType;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
@ -12,7 +11,12 @@ import com.ruoyi.common.enums.EncodeType;
* @author 老马 * @author 老马
* @date 2023-01-06 10:00 * @date 2023-01-06 10:00
*/ */
public class Base64Encryptor implements IEncryptor { public class Base64Encryptor extends AbstractEncryptor {
public Base64Encryptor(EncryptContext context) throws Exception {
super(context);
}
/** /**
* 获得当前算法 * 获得当前算法
* *
@ -25,18 +29,6 @@ public class Base64Encryptor implements IEncryptor {
return AlgorithmType.BASE64; return AlgorithmType.BASE64;
} }
/**
* 初始化加密者
*
* @param context 加密上下文
* @author 老马
* @date 2023/1/17 09:01
*/
@Override
public void init(EncryptContext context) {
// 无需初始化
}
/** /**
* 加密 * 加密
* *

View File

@ -6,7 +6,6 @@ import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA; import cn.hutool.crypto.asymmetric.RSA;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.AlgorithmType;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -18,10 +17,20 @@ import com.ruoyi.common.utils.StringUtils;
* @author 老马 * @author 老马
* @date 2023-01-06 09:37 * @date 2023-01-06 09:37
*/ */
public class RsaEncryptor implements IEncryptor { public class RsaEncryptor extends AbstractEncryptor {
private RSA rsa = null; private RSA rsa = null;
public RsaEncryptor(EncryptContext context) throws Exception {
super(context);
String privateKey = context.getPrivateKey();
String publicKey = context.getPublicKey();
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
throw new RuntimeException("rsa公私钥均需要提供公钥加密私钥解密。");
}
this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
}
/** /**
* 获得当前算法 * 获得当前算法
* *
@ -34,24 +43,6 @@ public class RsaEncryptor implements IEncryptor {
return AlgorithmType.RSA; return AlgorithmType.RSA;
} }
/**
* 初始化加密者
*
* @param context 加密上下文
* @throws Exception 抛出异常
* @author 老马
* @date 2023/1/17 09:01
*/
@Override
public void init(EncryptContext context) throws Exception {
String privateKey = context.getPrivateKey();
String publicKey = context.getPublicKey();
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
throw new RuntimeException("rsa公私钥均需要提供公钥加密私钥解密。");
}
this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey));
}
/** /**
* 加密 * 加密
* *

View File

@ -7,7 +7,6 @@ import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.crypto.asymmetric.SM2;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.AlgorithmType;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -18,10 +17,20 @@ import com.ruoyi.common.utils.StringUtils;
* @author 老马 * @author 老马
* @date 2023-01-06 17:13 * @date 2023-01-06 17:13
*/ */
public class Sm2Encryptor implements IEncryptor { public class Sm2Encryptor extends AbstractEncryptor {
private SM2 sm2 = null; private SM2 sm2 = null;
public Sm2Encryptor(EncryptContext context) throws Exception {
super(context);
String privateKey = context.getPrivateKey();
String publicKey = context.getPublicKey();
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
throw new RuntimeException("sm2公私钥均需要提供公钥加密私钥解密。");
}
this.sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));
}
/** /**
* 获得当前算法 * 获得当前算法
* *
@ -34,24 +43,6 @@ public class Sm2Encryptor implements IEncryptor {
return AlgorithmType.SM2; return AlgorithmType.SM2;
} }
/**
* 初始化加密者
*
* @param context 加密上下文
* @throws Exception 抛出异常
* @author 老马
* @date 2023/1/17 09:01
*/
@Override
public void init(EncryptContext context) throws Exception {
String privateKey = context.getPrivateKey();
String publicKey = context.getPublicKey();
if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
throw new RuntimeException("sm2公私钥均需要提供公钥加密私钥解密。");
}
this.sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));
}
/** /**
* 加密 * 加密
* *

View File

@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4; import cn.hutool.crypto.symmetric.SM4;
import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.EncryptContext;
import com.ruoyi.common.encrypt.IEncryptor;
import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.AlgorithmType;
import com.ruoyi.common.enums.EncodeType; import com.ruoyi.common.enums.EncodeType;
@ -17,10 +16,23 @@ import java.nio.charset.StandardCharsets;
* @author 老马 * @author 老马
* @date 2023-01-06 17:40 * @date 2023-01-06 17:40
*/ */
public class Sm4Encryptor implements IEncryptor { public class Sm4Encryptor extends AbstractEncryptor {
private SM4 sm4 = null; private SM4 sm4 = null;
public Sm4Encryptor(EncryptContext context) throws Exception {
super(context);
String password = context.getPassword();
if (StrUtil.isBlank(password)) {
throw new RuntimeException("sm4没有获得秘钥信息");
}
// sm4算法的秘钥要求是16位长度
if (16 != password.length()) {
throw new RuntimeException("sm4秘钥长度应该为16位实际为" + password.length() + "");
}
this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8));
}
/** /**
* 获得当前算法 * 获得当前算法
* *
@ -33,27 +45,6 @@ public class Sm4Encryptor implements IEncryptor {
return AlgorithmType.SM4; return AlgorithmType.SM4;
} }
/**
* 初始化加密者
*
* @param context 加密上下文
* @throws Exception 抛出异常
* @author 老马
* @date 2023/1/17 09:01
*/
@Override
public void init(EncryptContext context) throws Exception {
String password = context.getPassword();
if (StrUtil.isBlank(password)) {
throw new RuntimeException("sm4没有获得秘钥信息");
}
// sm4算法的秘钥要求是16位长度
if (16 != password.length()) {
throw new RuntimeException("sm4秘钥长度应该为16位实际为" + password.length() + "");
}
this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8));
}
/** /**
* 加密 * 加密
* *