在之前的系列教程中,我們已經介紹了非常多關於Spring Boot配置檔案中的各種細節用法,比如:引數間的引用、隨機數的應用、命令列引數的使用、多環境的配置管理等等。
這些配置相關的知識都是Spring Boot原生就提供的,而今天我們將介紹的功能並非Spring Boot原生就支援,但卻非常有用:配置內容的加密。
為什麼要加密?
可能很多初學者,對於配置資訊的加密並不敏感,因為開始主要接觸本地的開發,對於很多安全問題並沒有太多的考慮。而現實中,我們的配置檔案中,其實包含著大量與安全相關的敏感資訊,比如:資料庫的賬號密碼、一些服務的金鑰等。這些資訊一旦洩露,對於企業的重要資料資產,那是相當危險的。 所以,對於這些配置檔案中存在的敏感資訊進行加密,是每個成熟開發團隊都一定會去的事。
如果您是DD的老讀者,也許馬上會想到Spring Cloud Config就提供配置的加密功能,之前在我的Spring Cloud系列教程和《Spring Cloud微服務實戰》一書中都有詳細的介紹,感興趣的話可以點選《Spring Cloud構建微服務架構:分散式配置中心(加密解密)》一探究竟。
既然以前寫過類似內容,那為什麼還要寫呢?因為並不是所有的開發場景都會搭建Spring Cloud的那套基礎設施,同時也不一定會使用Spring Cloud Config作為配置中心。所以,本文主要說說,當我們只使用Spring Boot的時候,如何實現對配置中敏感資訊的加密。
動手試試
下面我們將使用https://github.com/ulisesbocchio/jasypt-spring-boot
這個開源專案提供的實現和外掛,來幫助我們輕鬆的完成配置資訊的加密。
趕緊跟著我下面的步驟動手試試吧!
第一步:建立一個基礎的Spring Boot專案(如果您還不會,可以參考這篇文章:快速入門
第二步:設計一個引數和單元測試,用來輸出這個配置資訊
準備加密的配置:
datasource.password=didispace.com
用來輸出配置資訊的單元測試:
@Slf4j
@SpringBootTest
public class PropertiesTest {
@Value("${datasource.password:}")
private String password;
@Test
public void test() {
log.info("datasource.password : {}", password);
}
}
執行這個單元測試,會輸出:
2021-08-13 22:28:45.506 INFO 70405 --- [ main] com.didispace.chapter15.PropertiesTest : datasource.password : didispace.com
這裡還沒開始加密,下面我們開始引入加密的操作!
第三步:在pom.xml
中引入jasypt提供的Spring Boot Starter
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
在外掛配置中加入:
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.3</version>
</plugin>
第四步:在配置檔案中加入加密需要使用的密碼
jasypt.encryptor.password=didispace
同時,修改要加密的內容,用DEC()
將待加密內容包裹起來,比如:
datasource.password=DEC(didispace.com)
第五步:使用jasypt-maven-plugin
外掛來給DEC()
包裹的內容實現批量加密。
在終端中執行下面的命令:
mvn jasypt:encrypt -Djasypt.encryptor.password=didispace
注意:這裡
-Djasypt.encryptor.password
引數必須與配置檔案中的一致,不然後面會解密失敗。
執行之後,重新檢視配置檔案,可以看到,自動變成了
datasource.password=ENC(/AL9nJENCYCh9Pfzdf2xLPsqOZ6HwNgQ3AnMybFAMeOM5GphZlOK6PxzozwtCm+Q)
jasypt.encryptor.password=didispace
其中,ENC()
跟DEC()
一樣都是jasypt提供的標識,分別用來標識括號內的是加密後的內容和待加密的內容。
如果當前配置檔案已經都是ENC()
內容了,那麼我們可以通過下面的命令來解密配置檔案,檢視原始資訊:
mvn jasypt:decrypt -Djasypt.encryptor.password=didispace
該操作不會修改配置檔案,只會在控制檯輸出解密結果,比如:
datasource.password=DEC(didispace.com)
jasypt.encryptor.password=didispace
第六步:此時,我們的配置檔案中的敏感資訊已經被ENC()
修飾了,再執行一下單元測試,不出意外的話,依然可以得到之前一樣的結果:
2021-08-13 22:50:00.463 INFO 76150 --- [ main] com.didispace.chapter15.PropertiesTest : datasource.password : didispace.com
而此時,配置檔案中已經是加密內容了,敏感資訊得到了保護。
本系列教程《Spring Boot 2.x基礎教程》點選直達! ,歡迎收藏與轉發!如果學習過程中如遇困難?可以加入我們Spring技術交流群 ,參與交流與討論,更好的學習與進步!
進一步思考
根據上面的步驟,愛思考的你,也許會發現這樣的問題:雖然敏感資訊是加密了,但是我們通過配置檔案也能看到jasypt.encryptor.password
資訊,我們是不是通過利用這個再把原始資訊解密出來,這樣的話豈不是還是不安全?
上面的實現方式的確是會有這樣的問題!所以,在實際應用的過程中,jasypt.encryptor.password
的配置,可以通過運維小夥伴在環境變數或啟動引數中注入,而不是由開發人員在配置檔案中指定。
同時,為了應對更高的安全要求,jasypt也提供自定義的加密解密方式,這裡就不做具體展開了,有興趣的小夥伴可以前往jasypt的倉庫檢視使用細節。
程式碼示例
本文的完整工程可以檢視下面倉庫中2.x
目錄下的chapter1-5
工程:
- Github:https://github.com/dyc87112/SpringBoot-Learning/
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/
如果您覺得本文不錯,歡迎Star
支援,您的關注是我堅持的動力!
歡迎關注我的公眾號:程式猿DD,分享外面看不到的乾貨與思考!