3 changed files with 216 additions and 115 deletions
@ -0,0 +1,213 @@ |
|||||
|
package com.zdxt.service.test; |
||||
|
|
||||
|
import org.dromara.common.encrypt.config.jasypt.CustomEncryptorConfig; |
||||
|
import org.junit.jupiter.api.*; |
||||
|
|
||||
|
import static org.junit.jupiter.api.Assertions.*; |
||||
|
|
||||
|
/** |
||||
|
* CustomEncryptorConfig 单元测试 |
||||
|
* <p> |
||||
|
* 验证项目自定义 Jasypt 加解密器(PBEWithMD5AndDES + 硬编码密钥 ATPfOhpnAVp6yBas7RU) |
||||
|
* 的加密、解密、幂等性以及异常处理是否符合预期。 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author zdxt |
||||
|
*/ |
||||
|
@DisplayName("CustomEncryptorConfig 单元测试") |
||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) |
||||
|
public class CustomEncryptorConfigTest { |
||||
|
|
||||
|
private static CustomEncryptorConfig encryptor; |
||||
|
|
||||
|
@BeforeAll |
||||
|
public static void init() { |
||||
|
encryptor = new CustomEncryptorConfig(); |
||||
|
} |
||||
|
|
||||
|
// ======================== 基础加解密 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(1) |
||||
|
@DisplayName("encrypt - 加密后密文不为空且与原文不同") |
||||
|
public void testEncrypt_producesNonEmptyCiphertext() { |
||||
|
String plainText = "hello_world_123"; |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
|
||||
|
assertNotNull(encrypted, "密文不应为 null"); |
||||
|
assertFalse(encrypted.isBlank(), "密文不应为空白"); |
||||
|
assertNotEquals(plainText, encrypted, "密文应与原文不同"); |
||||
|
System.out.println("原文: " + plainText + " -> 密文: " + encrypted); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(2) |
||||
|
@DisplayName("decrypt - 加密后再解密应还原为原文") |
||||
|
public void testDecrypt_restoresOriginalText() { |
||||
|
String plainText = "test_password_zdxt@1234"; |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
String decrypted = encryptor.decrypt(encrypted); |
||||
|
|
||||
|
assertEquals(plainText, decrypted, "解密结果应与原文一致"); |
||||
|
System.out.println("加解密验证通过: " + plainText + " -> " + encrypted + " -> " + decrypted); |
||||
|
} |
||||
|
|
||||
|
// ======================== 随机盐特性 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(3) |
||||
|
@DisplayName("encrypt - 同一原文多次加密产生不同密文(随机盐)") |
||||
|
public void testEncrypt_randomSaltProducesDifferentCiphertext() { |
||||
|
String plainText = "same_text_for_random_salt"; |
||||
|
|
||||
|
String encrypted1 = encryptor.encrypt(plainText); |
||||
|
String encrypted2 = encryptor.encrypt(plainText); |
||||
|
|
||||
|
assertNotEquals(encrypted1, encrypted2, "随机盐下,同一原文两次加密结果应不同"); |
||||
|
// 但两次密文都能正确解密还原
|
||||
|
assertEquals(plainText, encryptor.decrypt(encrypted1), "第一次密文应能正确解密"); |
||||
|
assertEquals(plainText, encryptor.decrypt(encrypted2), "第二次密文应能正确解密"); |
||||
|
|
||||
|
System.out.println("随机盐验证通过:"); |
||||
|
System.out.println(" 密文1: " + encrypted1); |
||||
|
System.out.println(" 密文2: " + encrypted2); |
||||
|
} |
||||
|
|
||||
|
// ======================== 各种输入类型 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(4) |
||||
|
@DisplayName("encrypt/decrypt - 含特殊字符的字符串") |
||||
|
public void testEncryptDecrypt_specialCharacters() { |
||||
|
String[] testCases = { |
||||
|
"zdxt@1234", |
||||
|
"jdbc:mysql://127.0.0.1:3306/db?useSSL=true&serverTimezone=GMT%2B8", |
||||
|
"p@$$w0rd!#%^&*()", |
||||
|
"中文密码测试", |
||||
|
"mixed_中英文_test_123!" |
||||
|
}; |
||||
|
|
||||
|
for (String plainText : testCases) { |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
String decrypted = encryptor.decrypt(encrypted); |
||||
|
assertEquals(plainText, decrypted, "特殊字符串加解密应一致: " + plainText); |
||||
|
} |
||||
|
System.out.println("特殊字符加解密验证通过,共 " + testCases.length + " 组"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(5) |
||||
|
@DisplayName("encrypt/decrypt - 空字符串") |
||||
|
public void testEncryptDecrypt_emptyString() { |
||||
|
String plainText = ""; |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
assertNotNull(encrypted, "空字符串加密后密文不应为 null"); |
||||
|
|
||||
|
String decrypted = encryptor.decrypt(encrypted); |
||||
|
assertEquals(plainText, decrypted, "空字符串加解密应一致"); |
||||
|
System.out.println("空字符串加解密验证通过"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(6) |
||||
|
@DisplayName("encrypt/decrypt - 超长字符串") |
||||
|
public void testEncryptDecrypt_longString() { |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
for (int i = 0; i < 100; i++) { |
||||
|
sb.append("LongText_").append(i).append("_"); |
||||
|
} |
||||
|
String plainText = sb.toString(); |
||||
|
|
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
String decrypted = encryptor.decrypt(encrypted); |
||||
|
|
||||
|
assertEquals(plainText, decrypted, "超长字符串加解密应一致"); |
||||
|
System.out.println("超长字符串(长度=" + plainText.length() + ")加解密验证通过"); |
||||
|
} |
||||
|
|
||||
|
// ======================== 异常场景 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(7) |
||||
|
@DisplayName("decrypt - 解密非法密文应抛出异常") |
||||
|
public void testDecrypt_invalidCiphertext() { |
||||
|
assertThrows(Exception.class, () -> encryptor.decrypt("invalid_base64_ciphertext"), |
||||
|
"解密非法密文应抛出异常"); |
||||
|
System.out.println("非法密文解密异常验证通过"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(8) |
||||
|
@DisplayName("decrypt - 解密被篡改的密文应抛出异常") |
||||
|
public void testDecrypt_tamperedCiphertext() { |
||||
|
String plainText = "original_text"; |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
|
||||
|
// 篡改密文(翻转第一个字符)
|
||||
|
char first = encrypted.charAt(0); |
||||
|
char tampered = (first == 'A') ? 'B' : 'A'; |
||||
|
String tamperedCiphertext = tampered + encrypted.substring(1); |
||||
|
|
||||
|
// 篡改后的密文解密要么抛异常,要么得到不同的结果
|
||||
|
try { |
||||
|
String result = encryptor.decrypt(tamperedCiphertext); |
||||
|
assertNotEquals(plainText, result, "篡改后的密文不应解密出原文"); |
||||
|
} catch (Exception e) { |
||||
|
// 抛异常也是合理的
|
||||
|
System.out.println("篡改密文解密抛出异常(预期行为): " + e.getClass().getSimpleName()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(9) |
||||
|
@DisplayName("encrypt - 加密 null 应抛出异常") |
||||
|
public void testEncrypt_nullInput() { |
||||
|
assertThrows(Exception.class, () -> encryptor.encrypt(null), |
||||
|
"加密 null 应抛出异常"); |
||||
|
System.out.println("null 输入加密异常验证通过"); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
@Order(10) |
||||
|
@DisplayName("decrypt - 解密 null 应抛出异常") |
||||
|
public void testDecrypt_nullInput() { |
||||
|
assertThrows(Exception.class, () -> encryptor.decrypt(null), |
||||
|
"解密 null 应抛出异常"); |
||||
|
System.out.println("null 输入解密异常验证通过"); |
||||
|
} |
||||
|
|
||||
|
// ======================== 与已有 ENC 密文兼容性 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(11) |
||||
|
@DisplayName("decrypt - 验证已有配置文件中的 ENC 密文可正常解密") |
||||
|
public void testDecrypt_existingEncValues() { |
||||
|
// application-dev.yml 中的 secretKey 密文
|
||||
|
String encSecretKey = "zTr/tj2VgFxQyunI4eIL7NyRWDPSMPSB0VlwTYeHTdsEWyu1H96xWw=="; |
||||
|
|
||||
|
try { |
||||
|
String decrypted = encryptor.decrypt(encSecretKey); |
||||
|
assertNotNull(decrypted, "配置文件中已有的 ENC 密文应能正常解密"); |
||||
|
assertFalse(decrypted.isBlank(), "解密结果不应为空白"); |
||||
|
System.out.println("已有 ENC 密文解密验证通过,解密结果长度: " + decrypted.length()); |
||||
|
} catch (Exception e) { |
||||
|
fail("配置文件中已有的 ENC 密文解密失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ======================== 一致性验证 ========================
|
||||
|
|
||||
|
@Test |
||||
|
@Order(12) |
||||
|
@DisplayName("encrypt/decrypt - 多次连续加解密结果一致") |
||||
|
public void testEncryptDecrypt_consistency() { |
||||
|
String plainText = "consistency_check_value"; |
||||
|
|
||||
|
for (int i = 0; i < 10; i++) { |
||||
|
String encrypted = encryptor.encrypt(plainText); |
||||
|
String decrypted = encryptor.decrypt(encrypted); |
||||
|
assertEquals(plainText, decrypted, "第 " + (i + 1) + " 次加解密结果不一致"); |
||||
|
} |
||||
|
System.out.println("连续 10 次加解密一致性验证通过"); |
||||
|
} |
||||
|
} |
||||
@ -1,112 +0,0 @@ |
|||||
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