Spring Boot 實(shí)現(xiàn)配置文件加解密原理
背景
接上文《失蹤人口回歸,mybatis-plus 3.3.2 發(fā)布》[1] ,提供了一個(gè)非常實(shí)用的功能 「數(shù)據(jù)安全保護(hù)」 功能,不僅支持?jǐn)?shù)據(jù)源的配置加密,對于 spring boot 全局的 yml /properties 文件均可實(shí)現(xiàn)敏感信息加密功能,在一定的程度上控制開發(fā)人員流動導(dǎo)致敏感信息泄露。
// 數(shù)據(jù)源敏感信息加密
spring: datasource: url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6BfaoEMZ1gVpPPhdDmjQqoM password: mpw:Hzy5iliJbwDHhjLs1L0j6w== username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==
// 數(shù)據(jù)源敏感信息加密
spring: redis: password: mpw:Hzy5iliJbwDHhjLs1L0j6w==
實(shí)現(xiàn)原理
我們翻開 spring boot 官方文檔,翻到 4.2.6 章節(jié) Spring Boot 不提供對加密屬性值的任何內(nèi)置支持,但是提供修改 Spring 環(huán)境中包含的值所必需的擴(kuò)展點(diǎn) EnvironmentPostProcessor 允許在應(yīng)用程序之前操作環(huán)境屬性值

mybatis-plus 的實(shí)現(xiàn)
public class SafetyEncryptProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
//命令行中獲取密鑰
String mpwKey = null;
// 返回全部形式的配置源(環(huán)境變量、命令行參數(shù)、配置文件 ...)
for (PropertySource<?> ps : environment.getPropertySources()) {
// 判斷是否需要含有加密密碼,沒有就直接跳過
if (ps instanceof SimpleCommandLinePropertySource) {
SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;
mpwKey = source.getProperty("mpw.key");
break;
}
}
//處理加密內(nèi)容(獲取到原有配置,然后解密放到新的map 里面(key是原有key))
HashMap<String, Object> map = new HashMap<>();
for (PropertySource<?> ps : environment.getPropertySources()) {
if (ps instanceof OriginTrackedMapPropertySource) {
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;
for (String name : source.getPropertyNames()) {
Object value = source.getProperty(name);
if (value instanceof String) {
String str = (String) value;
if (str.startsWith("mpw:")) {
map.put(name, AES.decrypt(str.substring(4), mpwKey));
}
}
}
}
}
// 將解密的數(shù)據(jù)放入環(huán)境變量,并處于第一優(yōu)先級上 (這里一定要注意,覆蓋其他配置)
if (!map.isEmpty()) {
environment.getPropertySources().addFirst(new MapPropertySource("custom-encrypt", map));
}
}
}
如何加載生效
resources/META-INF/spring.factories 配置 SPI
org.springframework.boot.env.EnvironmentPostProcessor=\ com.baomidou.mybatisplus.autoconfigure.SafetyEncryptProcessor
擴(kuò)展
mybatis-plus 默認(rèn)是讀取啟動參數(shù),可以在此處可以根據(jù)自己需求修改為更安全的根密鑰存儲。
讀取環(huán)境變量
System.getProperty("mpw.key")
遠(yuǎn)程加載密碼服務(wù)
// 此處思路,參考 druid ConfigFilter
public Properties loadConfig(String filePath) {
Properties properties = new Properties();
InputStream inStream = null;
try {
boolean xml = false;
if (filePath.startsWith("file://")) {
filePath = filePath.substring("file://".length());
inStream = getFileAsStream(filePath);
xml = filePath.endsWith(".xml");
} else if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
URL url = new URL(filePath);
inStream = url.openStream();
xml = url.getPath().endsWith(".xml");
} else if (filePath.startsWith("classpath:")) {
String resourcePath = filePath.substring("classpath:".length());
inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath);
// 在classpath下應(yīng)該也可以配置xml文件吧?
xml = resourcePath.endsWith(".xml");
} else {
inStream = getFileAsStream(filePath);
xml = filePath.endsWith(".xml");
}
if (inStream == null) {
LOG.error("load config file error, file : " + filePath);
return null;
}
if (xml) {
properties.loadFromXML(inStream);
} else {
properties.load(inStream);
}
return properties;
} catch (Exception ex) {
LOG.error("load config file error, file : " + filePath, ex);
return null;
} finally {
JdbcUtils.close(inStream);
}
}
總結(jié)
配置文件加解密,是通過自定義擴(kuò)展 EnvironmentPostProcessor 實(shí)現(xiàn)
若項(xiàng)目中沒有使用最新版本 mybatis-plus ,可以參考如上自己實(shí)現(xiàn),不過我推薦 jasypt-spring-boot-starter[2] ,原理類似實(shí)現(xiàn)了一個(gè) EnableEncryptablePropertySourcesPostProcessor ,但是支持的加密方式更多更成熟
關(guān)于 jasypt 使用可以參考源碼: https://gitee.com/log4j/pig
到此這篇關(guān)于Spring Boot 實(shí)現(xiàn)配置文件加解密原理的文章就介紹到這了,更多相關(guān)SpringBoot文件加解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot四大神器之Auto onfiguration的使用
本文主要介紹了SpringBoot四大神器之Auto Configuration,springboot auto configuration的本質(zhì)就是自動配置spring的各種bean。感興趣的可以了解一下2021-10-10
詳解Spring Boot對 Apache Pulsar的支持
Spring Boot通過提供spring-pulsar和spring-pulsar-reactive自動配置支持Apache Pulsar,類路徑中這些依賴存在時(shí),Spring Boot自動配置命令式和反應(yīng)式Pulsar組件,PulsarClient自動注冊,默認(rèn)連接本地Pulsar實(shí)例,感興趣的朋友一起看看吧2024-11-11
使用@Autowired注解引入server服務(wù)層方法時(shí)報(bào)錯(cuò)的解決
這篇文章主要介紹了使用@Autowired注解引入server服務(wù)層方法時(shí)報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java中實(shí)現(xiàn)token過期失效超時(shí)
在Java應(yīng)用程序中,為了確保安全性和保護(hù)用戶數(shù)據(jù),一種常見的做法是使用Token進(jìn)行身份驗(yàn)證和授權(quán),Token是由服務(wù)器生成的具有一定時(shí)效的令牌,用于識別和驗(yàn)證用戶身份,當(dāng)Token失效后,用戶將無法再進(jìn)行相關(guān)操作,從而提高系統(tǒng)的安全性2023-10-10
淺談Java包裝類型Long的==操作引發(fā)的低級bug
本文主要介紹了淺談Java包裝類型Long的==操作引發(fā)的低級bug,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
java 實(shí)現(xiàn)當(dāng)前時(shí)間加減30分鐘的時(shí)間代碼
這篇文章主要介紹了java 實(shí)現(xiàn)當(dāng)前時(shí)間加減30分鐘的時(shí)間代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Java如何優(yōu)雅地關(guān)閉資源try-with-resource及其異常抑制
這篇文章主要介紹了Java如何優(yōu)雅地關(guān)閉資源try-with-resource及其異常抑制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02

