SpringBoot整合Jasypt實(shí)現(xiàn)配置文件和數(shù)據(jù)庫字段敏感數(shù)據(jù)的加解密
1、前言
在我們?nèi)粘i_發(fā)中,很多時(shí)候?yàn)榱吮WC數(shù)據(jù)的安全,在處理敏感數(shù)據(jù)、前后端數(shù)據(jù)傳輸、數(shù)據(jù)庫敏感數(shù)據(jù)入庫等,數(shù)據(jù)的加密和解密是不可忽視的重要環(huán)節(jié),特別是一些政企項(xiàng)目這點(diǎn)就尤為重要,避免每一次安全審計(jì)后反復(fù)的調(diào)整,所以在系統(tǒng)設(shè)計(jì)之初我們就應(yīng)當(dāng)把數(shù)據(jù)安全的問題考慮進(jìn)去!
今天博主就給大家詳細(xì)介紹Jasypt-Spring-Boot的功能,并展示如何在Spring Boot項(xiàng)目中實(shí)現(xiàn)各種加解密操作
2、什么是Jasypt
Jasypt(Java Simplified Encryption)是一個(gè)用于加密和解密數(shù)據(jù)的Java庫。它提供了簡(jiǎn)單易用的API,可以輕松地將加密功能集成到Java應(yīng)用程序中。Jasypt支持多種加密算法,并且可以保護(hù)各種類型的數(shù)據(jù),包括文本、配置文件和數(shù)據(jù)庫字段等。
3、什么是Jasypt-Spring-Boot
Jasypt-Spring-Boot是一個(gè)用于在Spring Boot應(yīng)用程序中集成Jasypt的Starter。通過使用Jasypt-Spring-Boot,我們可以輕松地在Spring Boot項(xiàng)目中配置和使用Jasypt的加解密功能。
目前該庫已經(jīng)有2.8K的Star,且目前最新版本是 3.0.5

GitHub地址:https://github.com/ulisesbocchio/jasypt-spring-boot
4、接入初體驗(yàn)
在開始接入前首先構(gòu)建我們的 Spring Boot 項(xiàng)目, 引入相關(guān)依賴
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
4.1 yml配置方式
修改 Spring Boot 配置文件,增加密鑰
jasypt:
encryptor:
password: 123456
在 Spring Boot 啟動(dòng)類上 或配置類Configuration類上追加 @EnableEncryptableProperties注解
具體參數(shù)說明可以查看以下表格
| 配置項(xiàng) | 必填 | 默認(rèn)值 | 說明 |
|---|---|---|---|
| jasypt.encryptor.password | 是 | 設(shè)置密鑰 | |
| jasypt.encryptor.algorithm | 否 | PBEWITHHMACSHA512ANDAES_256 | 設(shè)置算法 |
| jasypt.encryptor.key-obtention-iterations | 否 | 1000 | 設(shè)置密鑰生成的迭代次數(shù) |
| jasypt.encryptor.pool-size | 否 | 1 | 設(shè)置加密池的大小 |
| jasypt.encryptor.provider-name | 否 | SunJCE | 設(shè)置加密提供者名稱 |
| jasypt.encryptor.provider-class-name | 否 | null | 設(shè)置加密提供類名 |
| jasypt.encryptor.salt-generator-classname | 否 | org.jasypt.salt.RandomSaltGenerator | 設(shè)置鹽值生成器的類名 |
| jasypt.encryptor.iv-generator-classname | 否 | org.jasypt.iv.RandomIvGenerator | 設(shè)置初始化向量生成器的類名 |
| jasypt.encryptor.string-output-type | 否 | base64 | 設(shè)置輸出字符串的編碼方式 |
| jasypt.encryptor.proxy-property-sources | 否 | false | |
| jasypt.encryptor.skip-property-sources | 否 | empty list |
最后一個(gè)屬性jasypt.encryptor.proxy-property-sources用于指示jasyp-spring-boot如何攔截屬性值以進(jìn)行解密
- 默認(rèn)值
false使用PropertySource、EnumerablePropertySource和MapPropertySource的自定義包裝器實(shí)現(xiàn)。 - 當(dāng)為該屬性指定
true時(shí),攔截機(jī)制將在每個(gè)特定的PropertySource實(shí)現(xiàn)上使用CGLib代理。這在某些必須保留原始PropertySource類型的場(chǎng)景中可能很有用
4.2 自定義配置類方式
創(chuàng)建一個(gè)自定義配置類:Bean名稱為: jasyptStringEncryptor
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableEncryptableProperties
public class StringEncryptorConfig {
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("password");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
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;
}
}
溫馨提示
- 在自定義StringEncryptor的時(shí)候,會(huì)覆蓋默認(rèn)的加密器,且Bean名稱固定為
jasyptStringEncryptor - 如果你需要自定義Bean名稱,則需要在springboot配置文件追加
jasypt.encryptor.bean = your encryptorBean Name
如下面自定義自定義Bean名稱
@Bean("encryptorBean")
public StringEncryptor stringEncryptor() {
//參考上面的配置參數(shù)
...
}
4.3 開始測(cè)試
我們現(xiàn)在來編寫一個(gè)測(cè)試類,來體驗(yàn)加解密的效果
@Resource(name = "jasyptStringEncryptor")
private StringEncryptor stringEncryptor;
@Test
public void testJasypt() {
String mysqlRoot = stringEncryptor.encrypt("root");
String mysqlPassword = stringEncryptor.encrypt("123456");
System.out.println("mysqlroot加密后:"+mysqlRoot);
System.out.println("mysqlPassword加密后:"+mysqlPassword);
System.out.println("===================");
System.out.println("mysqlRoot解密后:"+ stringEncryptor.decrypt(mysqlRoot));
System.out.println("mysqlPassword解密后:"+ stringEncryptor.decrypt(mysqlPassword));
}
測(cè)試輸出如下:

4.4 修改mysql參數(shù)加密
我們已經(jīng)獲得了mysql加密后的賬號(hào)以及密碼,現(xiàn)在我們來給mysql配置的明文賬戶密碼改一下
加密格式:默認(rèn)的前后綴是 ENC() 括號(hào)里是密文
# 數(shù)據(jù)源配置
spring:
#數(shù)據(jù)源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
url: jdbc:mysql://localhost:3306/docker_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# 未加密前
#username: root
#password: 123456
# 加密后
username: ENC(TBTl1fiJ7tilJ91sEdym6G8vEQG7Wn3QhIBU77mrfzCtqkHPMEMAihvpjokqUgMP)
password: ENC(9galEBTwYzgGG6ER3oY+k45463tkvYSnt+epH8SE/hldbi13hg3+XL7CPKpgJAQp)
啟動(dòng)SpringBoot項(xiàng)目。觀察控制臺(tái)輸出,數(shù)據(jù)庫是否完成連接初始化,且項(xiàng)目啟動(dòng)成功!

特別說明
小伙伴發(fā)現(xiàn)了在mysql的配置中,我們使用 ENC() 來包裹我們的密文,這個(gè)前后綴是可以修改的,如MICRO()
修改配置文件方式
jasypt:
encryptor:
property:
prefix: "MICRO["
suffix: "]"
編碼方式
我們可以通過創(chuàng)建一個(gè)名為 encryptablePropertyDetector 類型為 EncryptablePropertyDetector 的Bean來覆蓋默認(rèn)實(shí)現(xiàn),如果你需要修改默認(rèn)名稱,需要覆蓋屬性 jasypt.encryptor.property.detector-bean 并指定您希望給予bean的名稱
private static class MyEncryptablePropertyDetector implements EncryptablePropertyDetector {
@Override
public boolean isEncrypted(String value) {
if (value != null) {
return value.startsWith("MICRO");
}
return false;
}
@Override
public String unwrapEncryptedValue(String value) {
return value.substring("MICRO".length());
}
}
@Bean(name = "encryptablePropertyDetector")
public EncryptablePropertyDetector encryptablePropertyDetector() {
return new MyEncryptablePropertyDetector();
}
5、使用JVM啟動(dòng)參數(shù)設(shè)置密鑰
在我們 YML 配置方式中, jasypt.encryptor.password=123456 是明文的,有小伙伴會(huì)問,哎呀這不也是暴露了加密密鑰么? 要解決這個(gè)問題,我們可以使用JVM啟動(dòng)參數(shù)設(shè)置
在IDEA項(xiàng)目里 ,點(diǎn)擊 Edit Configurations ,添加 VM 啟動(dòng)參數(shù) -Djasypt.encryptor.password=123456


在生產(chǎn)環(huán)境部署jar包的時(shí)候,可以使用如下命令啟動(dòng):
java -jar your-project.jar --jasypt.encryptor.password=password
6、加密和解密數(shù)據(jù)庫字段
在我們公司某些項(xiàng)目中,用戶的敏感信息是不允許明文存儲(chǔ)數(shù)據(jù)庫的,比如手機(jī)號(hào)、身份證等,接下來我們來演示如何在實(shí)體類中使用Jasypt進(jìn)行數(shù)據(jù)庫字段實(shí)現(xiàn)加解密
注意引入JPA支持 spring-boot-starter-data-jpa
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.jasypt.util.text.AES256TextEncryptor;
@Component
@Converter
public class EncryptedStringConverter implements AttributeConverter<String, String> {
@Resource(name = "jasyptStringEncryptor")
private StringEncryptor stringEncryptor;
@Override
public String convertToDatabaseColumn(String attribute) {
return stringEncryptor.encrypt(attribute);
}
@Override
public String convertToEntityAttribute(String dbData) {
return stringEncryptor.decrypt(dbData);
}
}
然后在實(shí)體類中使用這個(gè)轉(zhuǎn)換器
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Convert(converter = EncryptedStringConverter.class)
@Column(name = "password")
private String password;
// Getters and Setters
}
7、結(jié)語
Jasypt-Spring-Boot是一個(gè)強(qiáng)大且易于使用的工具,可以在Spring Boot應(yīng)用程序中實(shí)現(xiàn)加密和解密操作。通過本文的介紹,我們了解了如何在Spring Boot項(xiàng)目中配置和使用Jasypt,并展示了各種加解密操作的實(shí)現(xiàn)方法。
以上就是SpringBoot整合Jasypt實(shí)現(xiàn)配置文件和數(shù)據(jù)庫字段敏感數(shù)據(jù)的加解密的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Jasypt加解密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SSM如何實(shí)現(xiàn)在Controller中添加事務(wù)管理
這篇文章主要介紹了SSM如何實(shí)現(xiàn)在Controller中添加事務(wù)管理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java高并發(fā)場(chǎng)景下的 HttpClient請(qǐng)求優(yōu)化實(shí)現(xiàn)
本文主要介紹了Java高并發(fā)場(chǎng)景下的 HttpClient請(qǐng)求優(yōu)化實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01
將Java項(xiàng)目提交到云服務(wù)器的流程步驟
所謂將項(xiàng)目提交到云服務(wù)器即將你的項(xiàng)目打成一個(gè) jar 包然后提交到云服務(wù)器即可,因此我們需要準(zhǔn)備服務(wù)器環(huán)境為:Linux + JDK + MariDB(MySQL)+ Git + Maven,文中通過圖文講解的非常詳細(xì),需要的朋友可以參考下2025-04-04
Spring項(xiàng)目中Ordered接口的應(yīng)用之全局過濾器(GlobalFilter)的順序控制
在Spring框架,尤其是Spring Cloud Gateway或Spring WebFlux項(xiàng)目中,Ordered接口扮演著重要的角色,特別是在實(shí)現(xiàn)全局過濾器(GlobalFilter)時(shí),用于控制過濾器執(zhí)行的優(yōu)先級(jí),下面將介紹如何在Spring項(xiàng)目中使用Ordered接口來管理Global Filter的執(zhí)行順序,需要的朋友可以參考下2024-06-06
基于Java事件監(jiān)聽編寫一個(gè)中秋猜燈謎小游戲
眾所周知,JavaSwing是Java中關(guān)于窗口開發(fā)的一個(gè)工具包,可以開發(fā)一些窗口程序,然后由于工具包的一些限制,導(dǎo)致Java在窗口開發(fā)商并沒有太多優(yōu)勢(shì),不過,在JavaSwing中關(guān)于事件的監(jiān)聽機(jī)制是我們需要重點(diǎn)掌握的內(nèi)容,本文將基于Java事件監(jiān)聽編寫一個(gè)中秋猜燈謎小游戲2023-09-09
Jmeter結(jié)構(gòu)體系及運(yùn)行原理順序解析
這篇文章主要介紹了Jmeter結(jié)構(gòu)體系及運(yùn)行原理順序解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Java在并發(fā)環(huán)境中SimpleDateFormat多種解決方案
這篇文章主要介紹了Java在并發(fā)環(huán)境中SimpleDateFormat多種解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

