Java 8
Spring Boot 2.7.3
Jasypt Spring Boot Starter 3.0.5 (jsypt 1.9.3)
IDE:Eclipse Version: 2022-09
--
序章
Jasypt 官網:
Jasypt 代碼庫:
https://github.com/jasypt/jasypt
About 信息:
About
Jasypt (Java Simplified Encryption) is a java library which allows the
developer to add basic encryption capabilities to his/her projects with
minimum effort, and without the need of having deep knowledge on how
cryptography works.
Jasypt Spring Boot Starter 版本信息:給 Spring Boot 集成用
添加依賴包:
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
項目版本信息 及 包依賴:
注意,Jasypt Spring Boot Starter 3.0.5 需要和 之前的版本的加密方式做區分。
使用 jasypt 後的 Bean
啓動項目,檢查 相關 Bean:
搜索 jas:
Line 122: com.ulisesbocchio.jasyptspringboot.configuration.EncryptablePropertyResolverConfiguration
Line 125: lazyJasyptStringEncryptor
Line 130: com.ulisesbocchio.jasyptspringboot.configuration.CachingConfiguration
Line 132: com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesConfiguration
Line 134: com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringBootAutoConfiguration
Line 134: com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringBootAutoConfiguration 同上 jas出現了兩次
搜索 crypt:
Line 122: com.ulisesbocchio.jasyptspringboot.configuration.EncryptablePropertyResolverConfiguration
Line 123: encryptablePropertySourceConverter
Line 125: lazyJasyptStringEncryptor
Line 126: lazyEncryptablePropertyDetector
Line 128: lazyEncryptablePropertyFilter
Line 129: lazyEncryptablePropertyResolver
Line 132: com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesConfiguration
Line 133: enableEncryptablePropertySourcesPostProcessor
測試加密、解密:main方法
本地運行。ben發佈於博客園
使用 StandardPBEStringEncryptor 執行:使用了一個 鹽值。
public static void main(String[] args) {
// 鹽值
String salt = "999999";
String mingWen = "12345 badfsd 千山萬水";
testJiaMi(salt, mingWen);
testJiaMi(salt, "mypwd123456");
testJiaMi(salt, "13344445555");
}
private static void testJiaMi(String salt, String mingWen) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(salt);
System.out.println(encryptor + ", " + encryptor.isInitialized());
System.out.println("測試結果:\r\nmingWen = " + mingWen + ", lenth=" + mingWen.length());
String miWen = encryptor.encrypt(mingWen);
System.out.println(" miWen = " + miWen);
String deMiWen = encryptor.decrypt(miWen);
System.out.println("deMiWen = " + deMiWen + ", lenth=" + deMiWen.length());
System.out.println(encryptor + ", " + encryptor.isInitialized());
System.out.println();
}
測試結果:成功。ben發佈於博客園
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@23ab930d, false
測試結果:
mingWen = 12345 badfsd 千山萬水, lenth=17
miWen = CX5146xzuR07LFTAEOaqMtIcfifrgZ0TzgdJUahzYZKpjnzKV3T27A==
deMiWen = 12345 badfsd 千山萬水, lenth=17
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@23ab930d, true
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@475530b9, false
測試結果:
mingWen = mypwd123456, lenth=11
miWen = UdRaipUB9z0HYXtNGCDC9RF5GVcJplEG
deMiWen = mypwd123456, lenth=11
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@475530b9, true
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@1d057a39, false
測試結果:
mingWen = 13344445555, lenth=11
miWen = SlOftyHgNu2HCrDkElV1HOJxdKFX0+hF
deMiWen = 13344445555, lenth=11
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@1d057a39, true
再次執行:鹽值 不變,但 密文變了。
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@23ab930d, false
測試結果:
mingWen = 12345 badfsd 千山萬水, lenth=17
miWen = MqtefEd8Rw5yKt871WHL2YXu1ZUeS6beasVv1e+LGpVX/LDD7GyIjA==
deMiWen = 12345 badfsd 千山萬水, lenth=17
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@23ab930d, true
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@475530b9, false
測試結果:
mingWen = mypwd123456, lenth=11
miWen = bZouQQwsrZpsA3IxlWSaEre8web0vvn8
deMiWen = mypwd123456, lenth=11
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@475530b9, true
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@1d057a39, false
測試結果:
mingWen = 13344445555, lenth=11
miWen = Zobj74KzPHO27b8RlynLosHrrVBzTbLQ
deMiWen = 13344445555, lenth=11
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@1d057a39, true
什麼是 StandardPBEStringEncryptor?
拷貝自 類的註釋:
* <p>
* Standard implementation of the {@link PBEStringEncryptor} interface.
* This class lets the user specify the algorithm (and provider) to be used for
* encryption, the password to use,
* the number of hashing iterations and the salt generator
* that will be applied for obtaining
* the encryption key.
* </p>
類定義:
package org.jasypt.encryption.pbe;
public final class StandardPBEStringEncryptor implements PBEStringCleanablePasswordEncryptor {
// 兩個構造函數
/**
* Creates a new instance of <tt>StandardPBEStringEncryptor</tt>.
*/
public StandardPBEStringEncryptor() {
super();
this.byteEncryptor = new StandardPBEByteEncryptor();
this.base64 = new Base64();
}
/*
* Creates a new instance of <tt>StandardPBEStringEncryptor</tt> using
* the specified byte encryptor (constructor used for cloning)
*/
private StandardPBEStringEncryptor(final StandardPBEByteEncryptor standardPBEByteEncryptor) {
super();
this.byteEncryptor = standardPBEByteEncryptor;
this.base64 = new Base64();
}
}
加密 Spring Boot 項目中配置文件的值
測試的配置文件:ben發佈於博客園
app:
# 明文版
ming:
pwd: mypwd123456
phone: 13344445555
# 密文版
mi:
pwd2: ENC(IwyG8h8pWvzYdoAKJf1yrlQDl8lP8NHy)
phone2: ENC(2dMUTBdi65iyPFNEWJNhq3y6Uhj0gIsb)
測試代碼:TestRunner.java
@Component
@Slf4j
public class TestRunner implements ApplicationRunner {
// 明文配置
@Value("${app.ming.pwd}")
private String pwd;
@Value("${app.ming.phone}")
private String phone;
// 密文配置
@Value("${app.mi.pwd2}")
private String pwd2;
@Value("${app.mi.phone2}")
private String phone2;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("啓動 TestRunner...");
print(pwd);
print(phone);
print(pwd2);
print(phone2);
}
private void print(String str) {
System.out.println("str = " + str + ", length = " + str.length() + "!");
}
}
啓動項目:發生錯誤。ben發佈於博客園
Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testRunner': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: either 'jasypt.encryptor.password', one of ['jasypt.encryptor.private-key-string', 'jasypt.encryptor.private-key-location'] for asymmetric encryption, or one of ['jasypt.encryptor.gcm-secret-key-string', 'jasypt.encryptor.gcm-secret-key-location', 'jasypt.encryptor.gcm-secret-key-password'] for AES/GCM encryption must be provided for Password-based or Asymmetric encryption AutowiredAnnotationBeanPostProcessor.java:405) ~[spring-beans-5.3.22.jar:5.3.22] |
缺少配置了。
添加配置 jasypt.encryptor.password :ben發佈於博客園
jasypt:
encryptor:
password: 999999
啓動項目:又出錯了
Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testRunner': Injection of autowired dependencies failed; nested exception is com.ulisesbocchio.jasyptspringboot.exception.DecryptionException: Unable to decrypt property: ENC(IwyG8h8pWvzYdoAKJf1yrlQDl8lP8NHy) resolved to: ENC(IwyG8h8pWvzYdoAKJf1yrlQDl8lP8NHy). Decryption of Properties failed, make sure encryption/decryption passwords match |
這應該和 使用的 Encryptor 有關。
默認使用的是 lazyJasyptStringEncryptor,而測試使用的是 StandardPBEStringEncryptor 對象。ben發佈於博客園
詳情如下:
lazyJasyptStringEncryptor
bean=
com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor@149f5761
class com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor
來源:https://github.com/ulisesbocchio/jasypt-spring-boot
由於使用的加密算法不同,該爲使用 默認的 lazyJasyptStringEncryptor (class com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor) 來加密得到字符串:
@Autowired
private DefaultLazyEncryptor lazyJasyptStringEncryptor;
print(lazyJasyptStringEncryptor.encrypt("mypwd123456")); // iMdrE/nYSuClCUv942aBdcd+NU8lA3vToVIVnjbOLCc=
print(lazyJasyptStringEncryptor.encrypt("13344445555")); // lZr2cBej3rl3PuB3x4S2eH9dq1EMXw1T9vd4FgV4VcM=
修改配置後啓動:ben發佈於博客園
# 必須:生成 密文時;解密密文時。
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES
password: 999999
app:
ming:
pwd: mypwd123456
phone: 13344445555
mi:
pwd2: ENC(iMdrE/nYSuClCUv942aBdcd+NU8lA3vToVIVnjbOLCc=)
phone2: ENC(lZr2cBej3rl3PuB3x4S2eH9dq1EMXw1T9vd4FgV4VcM=)
啓動成功:獲取到了 解密後的明文
啓動 TestRunner...
str = mypwd123456, length = 11!
str = 13344445555, length = 11!
str = mypwd123456, length = 11!
str = 13344445555, length = 11!
檢查 DefaultLazyEncryptor 的關係
public class DefaultLazyEncryptor implements StringEncryptor {
}
// 接口
public interface StringEncryptor {
}
和 StandardPBEStringEncryptor 的關係:都是 StringEncryptor 的 實現類。
public final class StandardPBEStringEncryptor implements PBEStringCleanablePasswordEncryptor {
}
public interface PBEStringCleanablePasswordEncryptor extends PBEStringEncryptor, CleanablePasswordBased {
}
public interface PBEStringEncryptor extends StringEncryptor, PasswordBased {
}
public interface PasswordBased {
}
定製 Encryptor
參考:
https://github.com/ulisesbocchio/jasypt-spring-boot
其中的“Use you own Custom Encryptor”。ben發佈於博客園
自測 使用 StandardPBEStringEncryptor 進行加解密。
添加 名爲 jasyptStringEncryptor 的 Bean:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean("jasyptStringEncryptor")
public StandardPBEStringEncryptor jasyptStringEncryptor() {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
EnvironmentStringPBEConfig pconf = new EnvironmentStringPBEConfig();
pconf.setAlgorithm("PBEWithMD5AndDES");
pconf.setPassword("pwd111222aaa");
encryptor.setConfig(pconf);
return encryptor;
}
}
添加工具類:ben發佈於博客園
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
public final class StandardPBEStringEncryptorUtils {
private static StandardPBEStringEncryptor encryptor;
static {
encryptor = new StandardPBEStringEncryptor();
EnvironmentStringPBEConfig pconf = new EnvironmentStringPBEConfig();
pconf.setAlgorithm("PBEWithMD5AndDES");
pconf.setPassword("pwd111222aaa");
encryptor.setConfig(pconf);
}
public static String encrypt(String mingWen) {
return encryptor.encrypt(mingWen);
}
public static String decrypt(String miWen) {
return encryptor.decrypt(miWen);
}
}
將需要加密的配置 加密:
app:
ming:
pwd: mypwd123456
phone: 13344445555
mi:
pwd2: ENC(hv/WdQoiV5SbdtQbF8Lpuz06NUQbpPpN)
phone2: ENC(lohQ0/L9YgPppIwUHrDC2ddgllWN24Uh)
啓動項目,測試:成功。ben發佈於博客園
啓動 TestRunner...
str = mypwd123456, length = 11!
str = 13344445555, length = 11!
str = mypwd123456, length = 11!
str = 13344445555, length = 11!
檢查 啓動後的Bean,發現 存在兩個 StringEncryptor:
jasyptStringEncryptor
bean=
org.jasypt.encryption.pbe.StandardPBEStringEncryptor@37d00a23
class org.jasypt.encryption.pbe.StandardPBEStringEncryptor
lazyJasyptStringEncryptor
bean=
com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor@39651a82
class com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor
另外的好消息:
使用 定製的 StandardPBEStringEncryptor 時,不需要配置 jasypt.encryptor.* 了。
進一步探索:
非對稱加密、EncryptionOperationNotPossibleException 異常 的處理(使用 jasypt.encryptor.algorithm = PBEWITHHMACSHA512ANDAES_256 時。)
---END---ben發佈於博客園
本文鏈接:
https://www.cnblogs.com/luo630/p/17154027.html
ben發佈於博客園
參考資料
1、jasypt-spring-boot
https://github.com/ulisesbocchio/jasypt-spring-boot
2、Spring Boot 配置文件密碼加密兩種方案
https://www.cnblogs.com/kexianting/p/11689289.html
3、使用jasypt 進行數據庫配置加密
https://blog.csdn.net/YISHENGYOUNI95/article/details/127518089
4、Jasypt加解密
by i笨笨i
已於 2022-11-11 12:11:00 修改
原文鏈接:https://blog.csdn.net/C_Karen/article/details/127803058
5、springboot的 加密依賴 導致的 出現異常EncryptionOperationNotPossibleException
by qq_43472248
於 2021-08-06 12:38:34 發佈
原文鏈接:https://blog.csdn.net/qq_43472248/article/details/119451546
6、
ben發佈於博客園