Spring?boot自定義加密解密數(shù)據(jù)庫連接配置示例代碼
前言
大家在日常工作中是否有對配置加密的要求呢?
可能你一下子就會想到,Jasypt作為標準的解決方案。不過,你有沒有想過先手動搓一個呢?
本文我們先來看看,如何手動寫一個加密解密配置的機制。
需求描述
對配置文件中的數(shù)據(jù)庫連接配置,執(zhí)行加密。確保上傳到git倉庫的配置以密文形式存在。
密鑰不會寫到配置文件,可以通過命令行參數(shù)或者環(huán)境變量的方式注入。保證安全性。
方案原理是:手動實現(xiàn)配置加解密+自定義DataSource Bean完成解密。
本場景針對數(shù)據(jù)庫連接配置進行加密解密。當然,其他的加密配置項也適用。
準備
- 數(shù)據(jù)庫實例,demo項目使用的是postgresql。
- 對稱加密工具類,可以實現(xiàn)加密解密。
- 自定義DataSource Bean配置類,在此配置類中實現(xiàn)對用戶名和密碼的解密后,再構(gòu)造DataSource對象。
/**
* 自定義數(shù)據(jù)源配置類
* 支持從命令行參數(shù)或環(huán)境變量讀取解密密鑰,解密數(shù)據(jù)庫用戶名和密碼后構(gòu)造 DataSource
*/
@Configuration
public class DataSourceSimpleConfig {
private static final Logger logger = LoggerFactory.getLogger(DataSourceSimpleConfig.class);
private static final String ENC_PREFIX = "{enc}";
// 密鑰獲取優(yōu)先級:命令行參數(shù) > 環(huán)境變量
@Value("${db.encrypt.key:#{systemEnvironment['ENCRYPT_KEY']}}")
private String encryptKey;
private final Environment environment;
public DataSourceSimpleConfig(Environment environment) {
this.environment = environment;
}
/**
* 自定義 DataSource Bean
* 解密數(shù)據(jù)庫配置后構(gòu)造 HikariDataSource
*/
@Bean
public DataSource dataSource() throws Exception {
logger.info("========== 開始配置數(shù)據(jù)源 ==========");
// 獲取原始配置
String url = environment.getProperty("spring.datasource.url");
String encryptedUsername = environment.getProperty("spring.datasource.username");
String encryptedPassword = environment.getProperty("spring.datasource.password");
String driverClassName = environment.getProperty("spring.datasource.driver-class-name");
// 檢查是否需要解密
String username;
String password;
if (encryptedUsername.startsWith(ENC_PREFIX)) {
// 需要解密用戶名
logger.info("檢測到加密的用戶名,開始解密...");
String encryptedUser = encryptedUsername.substring(ENC_PREFIX.length());
username = decrypt(encryptedUser, encryptKey);
logger.info("用戶名解密成功");
} else {
username = encryptedUsername;
logger.info("用戶名未加密,直接使用");
}
if (encryptedPassword.startsWith(ENC_PREFIX)) {
// 需要解密密碼
logger.info("檢測到加密的密碼,開始解密...");
String encryptedPass = encryptedPassword.substring(ENC_PREFIX.length());
password = decrypt(encryptedPass, encryptKey);
logger.info("密碼解密成功");
} else {
password = encryptedPassword;
logger.info("密碼未加密,直接使用");
}
// 創(chuàng)建 HikariConfig
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(url);
hikariConfig.setUsername(username);
hikariConfig.setPassword(password);
if (driverClassName != null && !driverClassName.isEmpty()) {
hikariConfig.setDriverClassName(driverClassName);
}
// 創(chuàng)建數(shù)據(jù)源
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
logger.info("? 數(shù)據(jù)源配置完成");
logger.info(" JDBC URL: {}", url);
logger.info("========== 數(shù)據(jù)源配置完成 ==========");
return dataSource;
}
/**
* 解密方法
*
* @param encryptedText 加密文本(Base64 編碼)
* @param key 解密密鑰(Base64 編碼)
* @return 解密后的明文
*/
private String decrypt(String encryptedText, String key) throws Exception {
try {
return AesUtil.decryptGCM(encryptedText, key);
} catch (Exception e) {
logger.error("? 解密失??!", e);
logger.error(" 錯誤信息: {}", e.getMessage());
throw new RuntimeException("解密失敗,請檢查密鑰是否正確", e);
}
}
}
- 準備密鑰,可以隨便寫。密鑰通過環(huán)境變量配置。
步驟
- 首先創(chuàng)建空白項目,配置完數(shù)據(jù)庫連接后,啟動項目并確認數(shù)據(jù)庫連接正常。
- 根據(jù)生成的密鑰,創(chuàng)建用戶名密碼的密文。并以特定的格式替換配置中原來的位置。
url: jdbc:postgresql://
username: "{enc}111111"
password: "{enc}222222"- 添加上一節(jié)準備好的
DataSourceSimpleConfig類。 - 在啟動配置中,添加密鑰環(huán)境變量配置
ENCRYPT_KEY="333333" - 啟動測試,可以看到仍然實現(xiàn)了正常連接。并且,對用戶名和密碼的解密日志也打印出來了
========== 開始配置數(shù)據(jù)源 ========== 檢測到加密的用戶名,開始解密... 已獲取解密密鑰(長度 4) 用戶名解密成功 檢測到加密的密碼,開始解密... 已獲取解密密鑰(長度 4) 密碼解密成功
測試環(huán)境
- JDK:17
- Spring boot:4.0.6
版本僅供參考,無強制要求。
總結(jié)
怎么樣,是不是很簡單!
經(jīng)過這么一番改造,上傳到git中的只有加密后的字符串。密鑰獨立配置提升了安全性。
對于當前示例這個方案足夠了。
但是,如果很多配置項都需要加密呢?這么一個一個寫,豈不是要累死?
解決方案就是拿數(shù)據(jù)庫當配置中心來用,將配置存儲到數(shù)據(jù)庫里就能避免傳入git了。所以,本文首先拿數(shù)據(jù)庫連接加密來試水。
下篇,我們來探討,如何將數(shù)據(jù)庫作為配置中心來使用,并在啟動時自動加載數(shù)據(jù)庫配置,敬請期待!
到此這篇關(guān)于Spring boot自定義加密解密數(shù)據(jù)庫連接配置的文章就介紹到這了,更多相關(guān)Springboot配置加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot自定義注解RateLimiter限流注解技術(shù)文檔詳解
文章介紹了限流技術(shù)的概念、作用及實現(xiàn)方式,通過Spring AOP攔截方法、緩存存儲計數(shù)器,結(jié)合注解、枚舉、異常類等核心組件,實現(xiàn)對訪問頻率的控制,旨在防止攻擊、保障系統(tǒng)穩(wěn)定、提升用戶體驗及節(jié)約成本2025-07-07
Mybatis如何使用@Mapper和@MapperScan注解實現(xiàn)映射關(guān)系
這篇文章主要介紹了Mybatis使用@Mapper和@MapperScan注解實現(xiàn)映射關(guān)系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10

