6 changed files with 189 additions and 3 deletions
@ -0,0 +1,44 @@ |
|||
package org.dromara.common.encrypt.config; |
|||
|
|||
import org.jasypt.encryption.StringEncryptor; |
|||
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; |
|||
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; |
|||
import org.springframework.boot.autoconfigure.AutoConfiguration; |
|||
import org.springframework.context.annotation.Bean; |
|||
|
|||
/** |
|||
* Jasypt 自定义加密器配置 |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@AutoConfiguration |
|||
public class CustomEncryptorConfig { |
|||
|
|||
/** |
|||
* 加密密钥 |
|||
*/ |
|||
private static final String CRACK = "ATPfOhpnAVp6yBas7RU"; |
|||
|
|||
@Bean("jasyptStringEncryptor") |
|||
public StringEncryptor jasyptStringEncryptor() { |
|||
return createEncryptor(); |
|||
} |
|||
|
|||
/** |
|||
* 创建加密器实例(Bean 注册和 main 方法共用) |
|||
*/ |
|||
private static PooledPBEStringEncryptor createEncryptor() { |
|||
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); |
|||
SimpleStringPBEConfig config = new SimpleStringPBEConfig(); |
|||
config.setPassword(CRACK); |
|||
config.setAlgorithm("PBEWithMD5AndDES"); |
|||
config.setKeyObtentionIterations("1000"); |
|||
config.setPoolSize("1"); |
|||
config.setProviderName("SunJCE"); |
|||
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); |
|||
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator"); |
|||
config.setStringOutputType("base64"); |
|||
encryptor.setConfig(config); |
|||
return encryptor; |
|||
} |
|||
} |
|||
@ -1,3 +1,4 @@ |
|||
org.dromara.common.encrypt.config.EncryptorAutoConfiguration |
|||
org.dromara.common.encrypt.config.ApiDecryptAutoConfiguration |
|||
org.dromara.common.encrypt.config.CustomEncryptorConfig |
|||
|
|||
|
|||
@ -0,0 +1,112 @@ |
|||
package com.zdxt.service.test; |
|||
|
|||
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; |
|||
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; |
|||
import org.junit.jupiter.api.*; |
|||
|
|||
/** |
|||
* Jasypt 加解密测试 |
|||
* <p> |
|||
* 与 CustomEncryptorConfig 使用相同的密钥和算法配置, |
|||
* 可直接运行获取加密后的密文用于配置文件 ENC(...) 占位。 |
|||
* </p> |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@DisplayName("Jasypt 加解密测试") |
|||
public class JasyptEncryptDecryptTest { |
|||
|
|||
private static final String CRACK = "ATPfOhpnAVp6yBas7RU"; |
|||
|
|||
private static PooledPBEStringEncryptor encryptor; |
|||
|
|||
@BeforeAll |
|||
public static void init() { |
|||
encryptor = new PooledPBEStringEncryptor(); |
|||
SimpleStringPBEConfig config = new SimpleStringPBEConfig(); |
|||
config.setPassword(CRACK); |
|||
config.setAlgorithm("PBEWithMD5AndDES"); |
|||
config.setKeyObtentionIterations("1000"); |
|||
config.setPoolSize("1"); |
|||
config.setProviderName("SunJCE"); |
|||
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); |
|||
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator"); |
|||
config.setStringOutputType("base64"); |
|||
encryptor.setConfig(config); |
|||
} |
|||
|
|||
@DisplayName("加密原文并输出密文") |
|||
@Test |
|||
public void testEncrypt() { |
|||
// ===== 修改此处为需要加密的原文 =====
|
|||
String plainText = "jdbc:mysql://localhost:3309/zfjd-refactoring-v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true"; |
|||
plainText="root"; |
|||
|
|||
String encrypted = encryptor.encrypt(plainText); |
|||
Assertions.assertNotNull(encrypted, "密文不应为 null"); |
|||
Assertions.assertFalse(encrypted.isBlank(), "密文不应为空"); |
|||
|
|||
System.out.println("========== 加密结果 =========="); |
|||
System.out.println("原文: " + plainText); |
|||
System.out.println("密文: " + encrypted); |
|||
System.out.println("配置文件使用: ENC(" + encrypted + ")"); |
|||
} |
|||
|
|||
@DisplayName("加密后解密应还原为原文") |
|||
@Test |
|||
public void testEncryptAndDecrypt() { |
|||
String plainText = "test_encrypt_decrypt_123"; |
|||
|
|||
String encrypted = encryptor.encrypt(plainText); |
|||
String decrypted = encryptor.decrypt(encrypted); |
|||
|
|||
Assertions.assertEquals(plainText, decrypted, "解密结果应与原文一致"); |
|||
System.out.println("加密解密验证通过: " + plainText + " -> " + encrypted + " -> " + decrypted); |
|||
} |
|||
|
|||
@DisplayName("同一原文多次加密应产生不同密文(随机盐)") |
|||
@Test |
|||
public void testRandomSaltProducesDifferentCiphertext() { |
|||
String plainText = "same_plain_text"; |
|||
|
|||
String encrypted1 = encryptor.encrypt(plainText); |
|||
String encrypted2 = encryptor.encrypt(plainText); |
|||
|
|||
Assertions.assertNotEquals(encrypted1, encrypted2, "随机盐下同一原文两次加密结果应不同"); |
|||
// 但两次密文都能正确解密
|
|||
Assertions.assertEquals(plainText, encryptor.decrypt(encrypted1)); |
|||
Assertions.assertEquals(plainText, encryptor.decrypt(encrypted2)); |
|||
System.out.println("随机盐验证通过:"); |
|||
System.out.println(" 密文1: " + encrypted1); |
|||
System.out.println(" 密文2: " + encrypted2); |
|||
} |
|||
|
|||
@DisplayName("解密错误密文应抛出异常") |
|||
@Test |
|||
public void testDecryptInvalidCiphertext() { |
|||
Assertions.assertThrows(Exception.class, () -> encryptor.decrypt("invalid_ciphertext"), |
|||
"解密非法密文应抛出异常"); |
|||
System.out.println("非法密文解密异常验证通过"); |
|||
} |
|||
|
|||
@DisplayName("批量加密 - 在此添加需要加密的原文") |
|||
@Test |
|||
public void testBatchEncrypt() { |
|||
// ===== 在此添加需要加密的原文列表 =====
|
|||
String[] plainTexts = { |
|||
"your_db_password", |
|||
"your_redis_password" |
|||
}; |
|||
|
|||
System.out.println("========== 批量加密结果 =========="); |
|||
for (String text : plainTexts) { |
|||
String encrypted = encryptor.encrypt(text); |
|||
System.out.println("原文: " + text); |
|||
System.out.println("配置: ENC(" + encrypted + ")"); |
|||
System.out.println("-----------------------------------"); |
|||
|
|||
// 验证可解密
|
|||
Assertions.assertEquals(text, encryptor.decrypt(encrypted)); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue