From 3969ccff8c4325432238421be879359280031848 Mon Sep 17 00:00:00 2001 From: mayuanfei Date: Tue, 17 Jan 2023 11:11:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A6=82=E4=B8=8B=EF=BC=9A?= =?UTF-8?q?=201.EncryptorManager=E4=BF=AE=E6=94=B9=E4=B8=BA=E9=87=87?= =?UTF-8?q?=E7=94=A8=E5=8F=8D=E5=B0=84=E5=88=9B=E5=BB=BA=E7=B1=BB=202.IEnc?= =?UTF-8?q?ryptor=E6=8E=A5=E5=8F=A3=E4=B8=AD=E5=A2=9E=E5=8A=A0=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E6=96=B9=E6=B3=95=203.=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8A=A0=E5=AF=86=E4=B8=8A=E4=B8=8B=E6=96=87=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=94=A8=E6=9D=A5=E9=9A=94=E7=A6=BB=E6=89=B9=E6=B3=A8=E5=92=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/common/encrypt/EncryptContext.java | 34 +++++++++++++++++++ .../com/ruoyi/common/encrypt/IEncryptor.java | 10 ++++++ .../com/ruoyi/common/enums/AlgorithmType.java | 12 +++---- .../com/ruoyi/common/enums/EncodeType.java | 10 ++---- .../java/com/ruoyi/demo/domain/TestDemo.java | 4 ++- .../framework/encrypt/EncryptorManager.java | 32 ++++++----------- .../encrypt/encryptor/AesEncryptor.java | 28 ++++++++++++--- .../encrypt/encryptor/Base64Encryptor.java | 13 +++++++ .../encrypt/encryptor/RsaEncryptor.java | 24 ++++++++++--- .../encrypt/encryptor/Sm2Encryptor.java | 24 ++++++++++--- .../encrypt/encryptor/Sm4Encryptor.java | 27 ++++++++++++--- 11 files changed, 166 insertions(+), 52 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/encrypt/EncryptContext.java diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/EncryptContext.java b/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/EncryptContext.java new file mode 100644 index 000000000..c74914095 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/EncryptContext.java @@ -0,0 +1,34 @@ +package com.ruoyi.common.encrypt; + +import com.ruoyi.common.enums.EncodeType; +import lombok.Data; + +/** + * 加密上下文。用于encryptor传递必要的参数。 + * 隔离配置和注解 + * + * @author 老马 + * @date 2023-01-17 08:31 + */ +@Data +public class EncryptContext { + /** + * 安全秘钥 + */ + private String password; + + /** + * 公钥 + */ + private String publicKey; + + /** + * 私钥 + */ + private String privateKey; + + /** + * 编码方式,base64/hex + */ + private EncodeType encode; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/IEncryptor.java b/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/IEncryptor.java index fae0327c1..946d55121 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/IEncryptor.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/encrypt/IEncryptor.java @@ -20,6 +20,16 @@ public interface IEncryptor { */ AlgorithmType algorithm(); + /** + * 初始化加密者 + * + * @param context 加密上下文 + * @throws Exception 抛出异常 + * @author 老马 + * @date 2023/1/17 09:01 + */ + void init(EncryptContext context) throws Exception; + /** * 加密 * diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/AlgorithmType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AlgorithmType.java index 610658fa9..8d99e5cec 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/AlgorithmType.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AlgorithmType.java @@ -14,27 +14,27 @@ public enum AlgorithmType { /** * base64 */ - BASE64("base64"), + BASE64("com.ruoyi.framework.encrypt.encryptor.Base64Encryptor"), /** * aes */ - AES("aes"), + AES("com.ruoyi.framework.encrypt.encryptor.AesEncryptor"), /** * rsa */ - RSA("rsa"), + RSA("com.ruoyi.framework.encrypt.encryptor.RsaEncryptor"), /** * sm2 */ - SM2("sm2"), + SM2("com.ruoyi.framework.encrypt.encryptor.Sm2Encryptor"), /** * sm4 */ - SM4("sm4"); + SM4("com.ruoyi.framework.encrypt.encryptor.Sm4Encryptor"); - private final String algorithm; + private final String clazz; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/EncodeType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/EncodeType.java index da50773b1..24cdab63a 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/EncodeType.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/EncodeType.java @@ -1,26 +1,20 @@ package com.ruoyi.common.enums; -import lombok.AllArgsConstructor; -import lombok.Getter; - /** * 编码类型 * * @author 老马 * @date 2023-01-11 11:39 */ -@Getter -@AllArgsConstructor public enum EncodeType { /** * base64编码 */ - BASE64("base64"), + BASE64, /** * 16进制编码 */ - HEX("hex"); + HEX; - private final String encode; } diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java index 66c2b365e..e32843a44 100644 --- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java @@ -46,12 +46,14 @@ public class TestDemo extends BaseEntity { /** * key键 */ - @EncryptField(algorithm=AlgorithmType.SM2, privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgZSlOvw8FBiH+aFJWLYZP/VRjg9wjfRarTkGBZd/T3N+gCgYIKoEcz1UBgi2hRANCAAR5DGuQwJqkxnbCsP+iPSDoHWIF4RwcR5EsSvT8QPxO1wRkR2IhCkzvRb32x2CUgJFdvoqVqfApFDPZzShqzBwX", publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEeQxrkMCapMZ2wrD/oj0g6B1iBeEcHEeRLEr0/ED8TtcEZEdiIQpM70W99sdglICRXb6KlanwKRQz2c0oaswcFw==") +// @EncryptField(algorithm=AlgorithmType.SM2, privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgZSlOvw8FBiH+aFJWLYZP/VRjg9wjfRarTkGBZd/T3N+gCgYIKoEcz1UBgi2hRANCAAR5DGuQwJqkxnbCsP+iPSDoHWIF4RwcR5EsSvT8QPxO1wRkR2IhCkzvRb32x2CUgJFdvoqVqfApFDPZzShqzBwX", publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEeQxrkMCapMZ2wrD/oj0g6B1iBeEcHEeRLEr0/ED8TtcEZEdiIQpM70W99sdglICRXb6KlanwKRQz2c0oaswcFw==") + @EncryptField(algorithm = AlgorithmType.RSA, privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANBBEeueWlXlkkj2+WY5l+IWe42d8b5K28g+G/CFKC/yYAEHtqGlCsBOrb+YBkG9mPzmuYA/n9k0NFIc8E8yY5vZQaroyFBrTTWEzG9RY2f7Y3svVyybs6jpXSUs4xff8abo7wL1Y/wUaeatTViamxYnyTvdTmLm3d+JjRij68rxAgMBAAECgYAB0TnhXraSopwIVRfmboea1b0upl+BUdTJcmci412UjrKr5aE695ZLPkXbFXijVu7HJlyyv94NVUdaMACV7Ku/S2RuNB70M7YJm8rAjHFC3/i2ZeIM60h1Ziy4QKv0XM3pRATlDCDNhC1WUrtQCQSgU8kcp6eUUppruOqDzcY04QJBAPm9+sBP9CwDRgy3e5+V8aZtJkwDstb0lVVV/KY890cydVxiCwvX3fqVnxKMlb+x0YtH0sb9v+71xvK2lGobaRECQQDVePU6r/cCEfpc+nkWF6osAH1f8Mux3rYv2DoBGvaPzV2BGfsLed4neRfCwWNCKvGPCdW+L0xMJg8+RwaoBUPhAkAT5kViqXxFPYWJYd1h2+rDXhMdH3ZSlm6HvDBDdrwlWinr0Iwcx3iSjPV93uHXwm118aUj4fg3LDJMCKxOwBxhAkByrQXfvwOMYygBprRBf/j0plazoWFrbd6lGR0f1uI5IfNnFRPdeFw1DEINZ2Hw+6zEUF44SqRMC+4IYJNc02dBAkBCgy7RvfyV/A7N6kKXxTHauY0v6XwSSvpeKtRJkbIcRWOdIYvaHO9L7cklj3vIEdwjSUp9K4VTBYYlmAz1xh03", publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQQRHrnlpV5ZJI9vlmOZfiFnuNnfG+StvIPhvwhSgv8mABB7ahpQrATq2/mAZBvZj85rmAP5/ZNDRSHPBPMmOb2UGq6MhQa001hMxvUWNn+2N7L1csm7Oo6V0lLOMX3/Gm6O8C9WP8FGnmrU1YmpsWJ8k73U5i5t3fiY0Yo+vK8QIDAQAB") private String testKey; /** * 值 */ + //@EncryptField(algorithm = AlgorithmType.SM4, password = "10rfylhtccpuyke5") @EncryptField(algorithm = AlgorithmType.AES, password = "10rfylhtccpuyke5") private String value; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/EncryptorManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/EncryptorManager.java index 0221a1ef5..bf9b1ddcd 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/EncryptorManager.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/EncryptorManager.java @@ -1,9 +1,11 @@ package com.ruoyi.framework.encrypt; +import cn.hutool.core.util.ReflectUtil; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; +import com.ruoyi.common.utils.BeanCopyUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.EncryptorProperties; -import com.ruoyi.framework.encrypt.encryptor.*; import lombok.extern.slf4j.Slf4j; import java.util.Map; @@ -36,26 +38,14 @@ public class EncryptorManager { if (encryptorMap.containsKey(encryptorKey)) { return encryptorMap.get(encryptorKey); } - switch (properties.getAlgorithm()) { - case BASE64: - encryptorMap.put(encryptorKey, new Base64Encryptor()); - break; - case AES: - encryptorMap.put(encryptorKey, new AesEncryptor(properties.getPassword())); - break; - case RSA: - encryptorMap.put(encryptorKey, new RsaEncryptor(properties.getPrivateKey(), properties.getPublicKey())); - break; - case SM2: - encryptorMap.put(encryptorKey, new Sm2Encryptor(properties.getPrivateKey(), properties.getPublicKey())); - break; - case SM4: - encryptorMap.put(encryptorKey, new Sm4Encryptor(properties.getPassword())); - break; - default: - Base64Encryptor defaultEncryptor = new Base64Encryptor(); - encryptorMap.put(encryptorKey, defaultEncryptor); + EncryptContext encryptContext = BeanCopyUtils.copy(properties, EncryptContext.class); + IEncryptor encryptor = ReflectUtil.newInstance(properties.getAlgorithm().getClazz()); + try { + encryptor.init(encryptContext); + } catch (Exception e) { + log.error("加密执行者注册失败。", e); } + encryptorMap.put(encryptorKey, encryptor); return encryptorMap.get(encryptorKey); } @@ -118,7 +108,7 @@ public class EncryptorManager { * @date 2023/1/11 17:39 */ private String getEncryptorKeyFromProperties(EncryptorProperties properties) { - return properties.getAlgorithm().getAlgorithm() + StringUtils.defaultString(properties.getPassword()) + + return properties.getAlgorithm() + StringUtils.defaultString(properties.getPassword()) + StringUtils.defaultString(properties.getPublicKey()) + StringUtils.defaultString(properties.getPrivateKey()); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/AesEncryptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/AesEncryptor.java index d3efa2444..8b343a559 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/AesEncryptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/AesEncryptor.java @@ -1,8 +1,11 @@ package com.ruoyi.framework.encrypt.encryptor; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.symmetric.AES; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.EncodeType; @@ -19,10 +22,6 @@ public class AesEncryptor implements IEncryptor { private AES aes = null; - public AesEncryptor(String password) { - aes = SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)); - } - /** * 获得当前算法 * @@ -35,6 +34,27 @@ public class AesEncryptor implements IEncryptor { 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)); + } + /** * 加密 * diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Base64Encryptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Base64Encryptor.java index aee34efaf..54b7a3ddd 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Base64Encryptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Base64Encryptor.java @@ -1,6 +1,7 @@ package com.ruoyi.framework.encrypt.encryptor; import cn.hutool.core.codec.Base64; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.EncodeType; @@ -24,6 +25,18 @@ public class Base64Encryptor implements IEncryptor { return AlgorithmType.BASE64; } + /** + * 初始化加密者 + * + * @param context 加密上下文 + * @author 老马 + * @date 2023/1/17 09:01 + */ + @Override + public void init(EncryptContext context) { + // 无需初始化 + } + /** * 加密 * diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/RsaEncryptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/RsaEncryptor.java index 4b0eea799..573c9e809 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/RsaEncryptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/RsaEncryptor.java @@ -5,9 +5,11 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.EncodeType; +import com.ruoyi.common.utils.StringUtils; /** @@ -20,10 +22,6 @@ public class RsaEncryptor implements IEncryptor { private RSA rsa = null; - public RsaEncryptor(String privateKey, String publicKey) { - this.rsa = SecureUtil.rsa(Base64.decode(privateKey), Base64.decode(publicKey)); - } - /** * 获得当前算法 * @@ -36,6 +34,24 @@ public class RsaEncryptor implements IEncryptor { 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)); + } + /** * 加密 * diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm2Encryptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm2Encryptor.java index 7e3727253..5ecae00bc 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm2Encryptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm2Encryptor.java @@ -6,9 +6,11 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.EncodeType; +import com.ruoyi.common.utils.StringUtils; /** * sm2算法实现 @@ -20,10 +22,6 @@ public class Sm2Encryptor implements IEncryptor { private SM2 sm2 = null; - public Sm2Encryptor(String privateKey, String publicKey) { - sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey)); - } - /** * 获得当前算法 * @@ -36,6 +34,24 @@ public class Sm2Encryptor implements IEncryptor { 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)); + } + /** * 加密 * diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm4Encryptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm4Encryptor.java index f028e90fc..1b83a0464 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm4Encryptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/encrypt/encryptor/Sm4Encryptor.java @@ -1,8 +1,10 @@ package com.ruoyi.framework.encrypt.encryptor; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.symmetric.SM4; +import com.ruoyi.common.encrypt.EncryptContext; import com.ruoyi.common.encrypt.IEncryptor; import com.ruoyi.common.enums.AlgorithmType; import com.ruoyi.common.enums.EncodeType; @@ -19,10 +21,6 @@ public class Sm4Encryptor implements IEncryptor { private SM4 sm4 = null; - public Sm4Encryptor(String password) { - this.sm4 = SmUtil.sm4(password.getBytes(StandardCharsets.UTF_8)); - } - /** * 获得当前算法 * @@ -35,6 +33,27 @@ public class Sm4Encryptor implements IEncryptor { 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)); + } + /** * 加密 *