Springboot之Jasypt配置文件加密/解密方式
一、Jasypt介紹
前言
在大多數(shù)項目中,配置文件中的 mysql 數(shù)據(jù)庫密碼、redis 密碼等其他敏感性密碼都是以明文形式存在,這種配置本身沒有任何問題,但是,在某些情況下,可能會對公司造成不可挽救的損失,比如:某一天,小明因為加班過度,頭腦發(fā)昏,不小心把公司項目上傳到自己的 GitHub 倉庫里面了,導致的后果就是,公司數(shù)據(jù)庫用戶名密碼泄露,被某些大佬加以利用…
所以,基于上面這種情況,加入配置文件中數(shù)據(jù)庫用戶密碼等其他敏感信息都是經(jīng)過加密處理過的呢???是不是可以大概率避免這種情況。Jasypt 因此應運而生。
什么是Jasypt?
Jasypt 是一個 java 庫,可以使開發(fā)者不需要太多操作來給 Java 項目添加基本加密功能,而且不需要知道加密原理。Jasypt 為開發(fā)人員提供了一種簡單易用加密功能,包括:密碼認證、字符串加密等。
Jasypt 有哪些特點?
- 高安全性、基于標準的加密技術(shù),適用于單向和雙向加密。加密密碼、文本、數(shù)字、二進制文件
- 適合集成到基于 Spring 的應用程序中
- 用于加密應用程序(即數(shù)據(jù)源)配置的集成功能
哪些信息要加密呢?
一般來說,項目配置文件里,所有涉及信息安全的配置項(或字段)都應該做處理,典型的比如:
- 數(shù)據(jù)庫密碼,如mysql
- 第三方緩存中間件的密碼,如 redis、mongodb
- 其他中間件,如消息中間件、zk、nacos等
- 各種第三方服務的 Access_Key
- …
二、Springboot整合Jasypt
2.1 環(huán)境配置
- SpringBoot2.0以上
- Jasypt 3.0.3
- jdk8
2.2 添加依賴
創(chuàng)建一個 Springboot 項目,項目版本 2.0 以上,并添加 Jasypt 相關(guān)依賴。
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2.3 添加Jasypt配置
jasypt:
encryptor:
# 鹽值
password: 123
# 指定加密方式
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
property:
# 標識為加密屬性的前綴
prefix: ENC(
# 標識為加密屬性的后綴
suffix: )
2.4 編寫加/解密工具類
public class JasyptUtil {
/**
* PBE 算法
*/
public static final String PBE_ALGORITHMS_MD5_DES = "PBEWITHMD5ANDDES";
public static final String PBE_ALGORITHMS_MD5_TRIPLEDES = "PBEWITHMD5ANDTRIPLEDES";
public static final String PBE_ALGORITHMS_SHA1_DESEDE = "PBEWITHSHA1ANDDESEDE";
public static final String PBE_ALGORITHMS_SHA1_RC2_40 = "PBEWITHSHA1ANDRC2_40";
private JasyptUtil() {
}
/**
* Jasypt 加密
*
* @param encryptedStr 加密字符串
* @param password 鹽值
* @return
*/
public static String encrypt(String encryptedStr, String password) {
return encrypt(encryptedStr, PBE_ALGORITHMS_MD5_DES, password);
}
/**
* Jasypt 加密
*
* @param encryptedStr 加密字符串
* @param algorithm 加密算法
* PBE ALGORITHMS: [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
* @param password 鹽值
* @return
*/
public static String encrypt(String encryptedStr, String algorithm, String password) {
// StandardPBEStringEncryptor、StandardPBEBigDecimalEncryptor、StandardPBEBigIntegerEncryptor、StandardPBEByteEncryptor
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
EnvironmentPBEConfig config = new EnvironmentPBEConfig();
// 指定加密算法
config.setAlgorithm(algorithm);
// 加密鹽值
config.setPassword(password);
//config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
encryptor.setConfig(config);
// 加密
return encryptor.encrypt(encryptedStr);
}
/**
* Jasypt 解密
*
* @param decryptStr 解密字符串
* @param password 鹽值
* @return
*/
public static String decrypt(String decryptStr, String password) {
return decrypt(decryptStr, PBE_ALGORITHMS_MD5_DES, password);
}
/**
* Jasypt 解密
*
* @param decryptStr 解密字符串
* @param algorithm 指定解密算法:解密算法要與加密算法一一對應
* PBE ALGORITHMS: [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
* @param password 鹽值
* @return
*/
public static String decrypt(String decryptStr, String algorithm, String password) {
// StandardPBEStringEncryptor、StandardPBEBigDecimalEncryptor、StandardPBEBigIntegerEncryptor、StandardPBEByteEncryptor
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
EnvironmentPBEConfig config = new EnvironmentPBEConfig();
// 指定解密算法:解密算法要與加密算法一一對應
config.setAlgorithm(algorithm);
// 加密秘鑰
config.setPassword(password);
//config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
encryptor.setConfig(config);
// 解密
return encryptor.decrypt(decryptStr);
}
public static void main(String[] args) {
String encryptedStr = "I am the string to be encrypted";
String algorithm = PBE_ALGORITHMS_SHA1_RC2_40;
String password = "salt";
String str = JasyptUtil.encrypt(encryptedStr, algorithm, password);
System.out.println("加密后的字符串:" + str);
System.out.println("解密后的字符串:" + JasyptUtil.decrypt(str, algorithm, password));
}
}
運行結(jié)果:

2.5 修改配置文件

如圖,通過編寫加/解密工具類得到對應的加密結(jié)果,然后將配置文件的原始明文密碼替換成上一步對應的結(jié)果,并通過 ENC(加密結(jié)果) 包裹起來。
2.5 如何進一步防止密碼泄露
在上面的內(nèi)容中,使用的是默認的加密規(guī)則,這一點會讓當自定義加密鹽值(jasypt.encryptor.password) 泄漏時可能變得不安全。那么如何進一步防止密碼泄露安全呢?
2.5.1 自定義加密器
為了進一步防止密碼泄露,我們可以自定義加密規(guī)則。
自定義加密規(guī)則非常簡單,只需要提供自定義的加密器配置類,然后通過jasypt.encryptor.bean配置指定加密配置類即可。
/**
* 自定義加密器
*/
public class MyStringEncryptor implements StringEncryptor {
/**
* 加解密PBE 算法
*/
public static final String PBE_ALGORITHMS_MD5_DES = "PBEWITHMD5ANDDES";
public static final String PBE_ALGORITHMS_MD5_TRIPLEDES = "PBEWITHMD5ANDTRIPLEDES";
public static final String PBE_ALGORITHMS_SHA1_DESEDE = "PBEWITHSHA1ANDDESEDE";
public static final String PBE_ALGORITHMS_SHA1_RC2_40 = "PBEWITHSHA1ANDRC2_40";
/**
* 加解密鹽值
*/
private String password;
/**
* 加解密算法
*/
private String algorithm = PBE_ALGORITHMS_MD5_DES;
public MyStringEncryptor(String password) {
this.password = password;
}
public MyStringEncryptor(String password, String algorithm) {
this.password = password;
this.algorithm = algorithm;
}
@Override
public String encrypt(String message) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
// 加解密鹽值
encryptor.setConfig(getConfig(this.password));
return encryptor.encrypt(message);
}
@Override
public String decrypt(String encryptedMessage) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setConfig(getConfig(this.password));
return encryptor.decrypt(encryptedMessage);
}
public SimpleStringPBEConfig getConfig(String password) {
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
// 加密鹽值
config.setPassword(password);
// 加解密算法
config.setAlgorithm(PBE_ALGORITHMS_MD5_DES);
// 設(shè)置密鑰獲取迭代次數(shù)
config.setKeyObtentionIterations(1000);
// 線程池大小:默認1
config.setPoolSize(1);
// 鹽值生成器className
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
// iv(initialization vector,初始化向量) 生成器className
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
// 設(shè)置字符串輸出類型
config.setStringOutputType("base64");
return config;
}
}
將自定義加密器添加到 Spring IoC 容器中。
@Configuration
public class JasyptConfig {
/**
* 加解密鹽值
*/
@Value("${jasypt.encryptor.password}")
private String password;
// @Bean("jasyptStringEncryptor")
@Bean("myStringEncryptor")
public StringEncryptor myStringEncryptor() {
return new MyStringEncryptor(password);
}
}
修改配置文件
jasypt:
encryptor:
# 指定加解密在spring ioc容器中bean的名稱,默認 jasyptStringEncryptor
bean: myStringEncryptor
# 鹽值
password: 123
注意:
Jasypt默認加解密器beanName為jasyptStringEncryptor,如果不想在配置文件中指定自定義加密器名稱,需將自定義加密器beanName設(shè)置為jasyptStringEncryptor,否則將不生效。
2.5.3 加密鹽值通過環(huán)境變量指定
- 方式一:直接作為程序啟動時的命令行參數(shù)
java -jar app.jar --jasypt.encryptor.password=salt
- 方式二:直接作為程序啟動時的應用環(huán)境變量
java -Djasypt.encryptor.password=salt -jar app.jar
- 方式三:直接作為系統(tǒng)環(huán)境變量
# 1. 設(shè)置系統(tǒng)環(huán)境變量 JASYPT_ENCRYPTOR_PASSWORD = salt
# 2. Spring Boot的項目配置文件指定系統(tǒng)環(huán)境變量:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用條件語句和循環(huán)結(jié)構(gòu)確定控制流(實例)
下面小編就為大家?guī)硪黄狫ava使用條件語句和循環(huán)結(jié)構(gòu)確定控制流(實例)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
淺析SpringBoot實現(xiàn)防盜鏈的五大常見漏洞和解決方法
文章詳細分析了Spring?Boot防盜鏈的五大致命漏洞,包括僅依賴Referer校驗,未處理CDN代理穿透問題,不使用動態(tài)Token驗證和未實現(xiàn)流量監(jiān)控與異常處理,每個漏洞都提供了代碼示例,并給出了解決方案2026-05-05
Spring boot事件監(jiān)聽實現(xiàn)過程解析
這篇文章主要介紹了,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
springboot項目整合mybatis并配置mybatis中間件的實現(xiàn)
這篇文章主要介紹了springboot項目整合mybatis并配置mybatis中間件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04

