Spring Boot 應用中實現配置文件敏感信息加密解密方案

Spring Boot 應用中實現配置文件敏感信息加密解密方案

  • 背景與挑戰 🚩
  • 一、設計目標 🎯
  • 二、整體啟動流程 🔄
  • 三、方案實現詳解 ??
    • 3.1 配置解密入口:`EnvironmentPostProcessor`
    • 3.2 通用解密工具類:`EncryptionTool`
  • 四、快速上手指南 ?
    • 4.1 依賴引入
    • 4.2 注冊 `EnvironmentPostProcessor`
    • 4.3 生成密鑰
    • 4.4 配置示例
    • 4.5 啟動注入密鑰
  • 五、安全最佳實踐 🔐
  • 六、總結 🎉


背景與挑戰 🚩

在現代企業級應用中,application.ymlapplication.properties 常用于配置數據庫(DataSource)、Redis、RabbitMQ 等中間件的連接信息。

spring:datasource:username: myuserpassword: my-secret-password

但問題來了:

將明文密碼直接寫入配置文件中存在諸多風險,主要包括:

? 風險類型詳細描述
代碼倉庫泄露風險配置文件可能被誤提交到 Git 等版本管理系統,導致敏感信息外泄。
構建與發布風險打包過程或日志文件可能暴露敏感數據,帶來安全隱患。
調試與共享風險第三方人員或調試時可能接觸到明文,增加信息暴露概率。

因此,敏感信息必須避免以明文形式存儲。

一、設計目標 🎯

目標說明
🔒 零明文配置配置文件中敏感字段均以 ENC(...) 形式存儲,無明文密碼。
?? 自動解密應用啟動時自動解密,業務代碼無感知,無需改動。
🔄 多算法支持兼容 RSA、AES 等主流加密算法,滿足不同安全需求。
🎛? 開關靈活支持配置及環境變量動態啟停解密功能,滿足多環境多場景。
🤝 無侵入業務代碼保持 Spring Boot 原生配置機制,業務層透明使用解密后的配置。

二、整體啟動流程 🔄

  1. 密鑰注入

    通過環境變量(如 DB_SECRET_KEY)注入 RSA 私鑰或對稱密鑰。

  2. EnvironmentPostProcessor 掃描

    Spring Boot 啟動時自動加載實現了 EnvironmentPostProcessor 的解密組件。

  3. 配置源掃描

    遍歷所有 PropertySource,查找形如 ENC(...) 的密文字段。

  4. 調用解密工具

    根據配置的算法(RSA/AES)還原明文。

  5. 注入環境變量

    將解密后的結果以 MapPropertySource 形式優先加載,覆蓋原加密值。

  6. 后續加載

    DataSource、Redis、RabbitMQ 等配置自動獲得解密后的明文。

在這里插入圖片描述

三、方案實現詳解 ??

3.1 配置解密入口:EnvironmentPostProcessor

利用 Spring Boot 啟動機制的 EnvironmentPostProcessor,啟動早期掃描并解密所有配置文件中的敏感字段。

@Slf4j
public class DecryptEnvPostProcessor implements EnvironmentPostProcessor {// 預定義需要解密的配置項 key,只對這些 key 進行解密處理private static final Set<String> ENCRYPTED_KEYS = Set.of("spring.datasource.password","custom.service.password");@Overridepublic void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {boolean enabled = Boolean.parseBoolean(env.getProperty("config.decrypt.enabled", "true"));if (!enabled) {log.info("配置解密功能已關閉,跳過解密流程");return;}String key = System.getenv("DB_SECRET_KEY");if (StringUtils.isBlank(key)) {throw new IllegalStateException("缺少解密密鑰(DB_SECRET_KEY),無法完成解密");}Map<String, Object> decryptedValues = new HashMap<>();for (PropertySource<?> source : env.getPropertySources()) {if (source instanceof EnumerablePropertySource<?> eps) {for (String name : eps.getPropertyNames()) {if (ENCRYPTED_KEYS.contains(name)) {Object val = eps.getProperty(name);if (val instanceof String s && s.startsWith("ENC(") && s.endsWith(")")) {String cipherText = s.substring(4, s.length() - 1);try {String plainText = EncryptionTool.decrypt(key, cipherText, "RSA");decryptedValues.put(name, plainText);} catch (Exception e) {log.warn("解密配置項 [{}] 失敗,保持原密文", name, e);}}}}}}if (!decryptedValues.isEmpty()) {env.getPropertySources().addFirst(new MapPropertySource("decryptedProperties", decryptedValues));}log.info("配置文件敏感信息解密完成");}
}

關鍵點說明:

  • 配置掃描與解密:支持 YAML、properties、環境變量等多種配置源。

  • 解密開關靈活控制:通過 config.decrypt.enabled 配置項動態啟用或禁用解密邏輯。

  • 優先級注入:通過 addFirst 優先注入解密后的配置,確保后續 Bean 讀取時獲得明文。

  • 異常安全:解密異常僅警告,保證啟動流程不受阻斷。

拓展建議

  • 建議將 ENCRYPTED_KEYS 設計為項目可配置項,甚至支持通配符或注解形式,提高靈活性。

  • addFirst 保證解密后的配置覆蓋原加密內容,確保業務讀取到明文。

3.2 通用解密工具類:EncryptionTool

支持多種主流加密算法,默認實現 RSA 和 AES,使用 Base64 作為密鑰和密文的編碼方式。

public class EncryptionTool {private static final String RSA = "RSA";public static String decrypt(String key, String cipherText, String algorithm) throws Exception {if (RSA.equalsIgnoreCase(algorithm)) {return decryptByPrivateKey(cipherText, key);} else {SecretKey secretKey = decodeKey(key, algorithm);Cipher cipher = Cipher.getInstance(algorithm);cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));return new String(decrypted, StandardCharsets.UTF_8);}}private static String decryptByPrivateKey(String cipherText, String base64PrivateKey) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);PrivateKey privateKey = KeyFactory.getInstance(RSA).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));Cipher cipher = Cipher.getInstance(RSA);cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));return new String(decryptedBytes, StandardCharsets.UTF_8);}private static SecretKey decodeKey(String encodedKey, String algorithm) {byte[] decodedKey = Base64.getDecoder().decode(encodedKey);return new SecretKeySpec(decodedKey, algorithm);}
}

拓展建議

  • 可實現更多算法,如 DESede(3DES)、ChaCha20,滿足不同安全合規需求。

  • 對于性能敏感場景,可考慮解密緩存策略。

四、快速上手指南 ?

4.1 依賴引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>

4.2 注冊 EnvironmentPostProcessor

  1. 在Spring Boot 項目的 resources 目錄下添加一個文件

    src/main/resources/META-INF/spring.factories
    

    ?? 注意:路徑和文件名都必須完全正確!

  2. 文件內容示例

    org.springframework.boot.env.EnvironmentPostProcessor=\
    com.example.config.DecryptionEnvironmentPostProcessor
    
    • com.example.config.DecryptionEnvironmentPostProcessor 替換成你自己的類的完整包名。

    • 逗號分隔可以注冊多個 EnvironmentPostProcessor

    • 必須沒有拼寫錯誤,且類必須能被 Spring Boot classpath 加載。

  3. 示例項目結構(最小可運行)

    your-project/
    ├── src/
    │   └── main/
    │       ├── java/
    │       │   └── com/example/config/
    │       │       └── DecryptionEnvironmentPostProcessor.java
    │       └── resources/
    │           └── META-INF/
    │               └── spring.factories
    ├── pom.xml
    

4.3 生成密鑰

算法說明工具示例
RSA生成一對公私鑰,私鑰需 PKCS#8 格式 Base64 編碼OpenSSL, Keytool
AES生成 128/256 位隨機密鑰,Base64 編碼OpenSSL, Java KeyGenerator

4.4 配置示例

spring:datasource:username: db_userpassword: ENC(rGA1bK3t...EncryptedText...)config:decrypt:enabled: true

4.5 啟動注入密鑰

export DB_SECRET_KEY=$(cat /etc/secure/rsa_private_key.pem)
java -jar app.jar --spring.profiles.active=prod

五、安全最佳實踐 🔐

建議說明
🔑 專業密鑰管理使用 Vault、AWS KMS、Azure Key Vault 等專業平臺管理密鑰,杜絕硬編碼及磁盤持久化。
🛡? 最小權限原則嚴格限制密鑰環境變量或文件權限,避免非授權訪問。
📜 日志審計控制絕不在日志中輸出明文或解密結果,防止敏感信息泄露。
🔄 定期密鑰輪換定期更新密鑰,縮短密鑰生命周期,降低風險。
🔍 分級加密策略針對不同環境/服務使用獨立密鑰,降低橫向攻擊風險。

六、總結 🎉

借助本方案,可以實現:

  • 🕵??♂? 配置文件零明文:徹底消除明文密碼泄露風險

  • 🚀 啟動自動解密:業務代碼無侵入,透明使用明文配置

  • 🔄 多算法靈活支持:滿足多場景安全合規需求

  • 🎛? 開關靈活控制:方便多環境適配,快速切換

  • 🛡? 安全規范完善:符合企業級安全管理最佳實踐

本方案不僅滿足高安全標準,還保持了 Spring Boot 配置體系的自然兼容與開發便利性。建議結合項目實際,進一步擴展支持密鑰動態更新、配置加密校驗等高級特性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82406.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82406.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82406.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV CUDA模塊特征檢測------角點檢測的接口createMinEigenValCorner()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數創建一個 基于最小特征值&#xff08;Minimum Eigenvalue&#xff09;的角點響應計算對象&#xff0c;這是另一種經典的角點檢測方法&…

性能優化 - 理論篇:CPU、內存、I/O診斷手段

文章目錄 Pre引言1. CPU 性能瓶頸1.1 top 命令 —— 多維度 CPU 使用率指標1.2 負載&#xff08;load&#xff09;——任務排隊情況1.3 vmstat 命令 —— CPU 繁忙與等待 2. 內存性能瓶頸2.1 操作系統層面的內存分布2.2 top 命令 —— VIRT / RES / SHR 三個關鍵列2.3 CPU 緩存…

GPIO的內部結構與功能解析

一、GPIO總體結構 總體構成 1.APB2(外設總線) APB2總線是微控制器內部連接CPU與外設&#xff08;如GPIO&#xff09;的總線&#xff0c;負責CPU對GPIO寄存器的讀寫訪問&#xff0c;支持低速外設通信 2.寄存器 控制GPIO的配置&#xff08;輸入/輸出模式、上拉/下拉等&#x…

汽車總線分析總結(CAN、LIN、FlexRay、MOST、車載以太網)

目錄 一、汽車總線技術概述 二、主流汽車總線技術對比分析 1. CAN總線&#xff08;Controller Area Network&#xff09; 2. LIN總線&#xff08;Local Interconnect Network&#xff09; 3. FlexRay總線 4. MOST總線&#xff08;Media Oriented Systems Transport&#x…

WordPress 6.5版本帶來的新功能

WordPress 6.5正式上線了&#xff01;WordPress團隊再一次為我們帶來了許多新的改進。在全球開發者的共同努力下&#xff0c;WordPress推出了許多新的功能&#xff0c;本文將對其進行詳細總結。 Hostease的虛擬主機現已支持一鍵安裝最新版本的WordPress。對于想要體驗WordPres…

【vue+ts】找不到模塊“./App.vue”或其相應的類型聲明

報錯&#xff1a;找不到模塊“./App.vue”或其相應的類型聲明。 原因&#xff1a;typescript只能理解.ts文件&#xff0c;無法理解.vue文件。 解決&#xff1a;在src/env.d.ts下添加&#xff1a; /// <reference types"vite/client" /> // 三斜線引用告訴編譯…

Nginx+Tomcat 負載均衡群集

目錄 一&#xff0c;部署Tomcat 1&#xff0c;案例概述 2&#xff0c;案例前置知識點 &#xff08;1&#xff09;Tomcat簡介 &#xff08;2&#xff09;應用場景 3&#xff0c;案例實施 3.1&#xff0c;實施準備 &#xff08;1&#xff09;關閉firewalld防火墻 &#…

Spring Boot Actuator未授權訪問漏洞修復

方案1&#xff1a;在網關的配置文件里增加以下配置 management:endpoints:web:exposure:include: []enabled-by-default: falseendpoint:health:show-details: ALWAYS 方案二&#xff1a;直接在nginx配置攔截actuator相關接口 location /actuator { return 403; …

動態規劃之網格圖模型(二)

文章目錄 動態規劃之網格圖模型&#xff08;二&#xff09;LeetCode 931. 下降路徑最小和思路Golang 代碼 LeetCode 2684. 矩陣中移動的最大次數思路Golang 代碼 LeetCode 2304. 網格中的最小路徑代價思路Golang 代碼 LeetCode 1289. 下降路徑最小和 II思路Golang 代碼 LeetCod…

React 編譯器

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

mac下通過anaconda安裝Python

本次分享mac下通過anaconda安裝Python、Jupyter Notebook、R。 anaconda安裝 點擊&#x1f449;https://www.anaconda.com/download&#xff0c; 點擊Mac系統安裝包&#xff0c; 選擇Mac芯片&#xff1a;蘋果芯片 or intel芯片&#xff0c; 選擇蘋果芯片圖形界面安裝&#x…

Pandas 技術解析:從數據結構到應用場景的深度探索

序 我最早用Python做大數據項目時&#xff0c;接觸最早的就是Pandas了。覺得對于IT技術人員而言&#xff0c;它是可以屬于多場景的存在&#xff0c;因為它的本身就是數據驅動的技術生態中&#xff0c;對于軟件工程師而言&#xff0c;它是快速構建數據處理管道的基石&#xff1…

【循環神經網絡RNN第一期】循環神經網絡RNN原理概述

目錄 &#x1f9e0; 什么是循環神經網絡&#xff08;RNN&#xff09;&#xff1f;&#x1f501; RNN 的結構圖&#x1f504; RNN 的“記憶”與問題RNN梯度推導 &#x1f9ec; LSTM&#xff1a;解決長期依賴問題&#x1f9f1; LSTM 的核心結構LSTM總結 參考 人類在思考的時候&am…

代碼隨想錄算法訓練營 Day60 圖論Ⅹ Bellmen_ford 系列算法

圖論 題目 94. 城市間貨物運輸 I Bellmen_ford 隊列優化算法 SPFA 大家可以發現 Bellman_ford 算法每次松弛 都是對所有邊進行松弛。 但真正有效的松弛&#xff0c;是基于已經計算過的節點在做的松弛。 本圖中&#xff0c;對所有邊進行松弛&#xff0c;真正有效的松弛&#…

Juce實現Table自定義

Juce實現Table自定義 一.總體展示概及概述 在項目中Juce中TableList往往無法滿足用戶需求&#xff0c;頭部和背景及背景顏色設置以及在Cell中添加自定義按鈕&#xff0c;所以需要自己實現自定義TabelList&#xff0c;該示例是展示實現自定義TableList&#xff0c;實現自定義標…

C++ set數據插入、set數據查找、set數據刪除、set數據統計、set排序規則、代碼練習1、2

set數據插入&#xff0c;代碼見下 #include<iostream> #include<set> #include<vector>using namespace std;void printSet(const set<int>& s) {for (set<int>::const_iterator it s.begin(); it ! s.end(); it) {cout << *it <…

深度學習賦能圖像識別:技術、應用與展望

論文&#xff1a; 一、引言? 1.1 研究背景與意義? 在當今數字化時代&#xff0c;圖像作為信息的重要載體&#xff0c;廣泛存在于各個領域。圖像識別技術旨在讓計算機理解和識別圖像內容&#xff0c;將圖像中的對象、場景、行為等信息轉化為計算機能夠處理的符號或數據 &am…

深入解析C++引用:從別名機制到函數特性實踐

1.C引用 1.1引用的概念和定義 引用不是新定義?個變量&#xff0c;而是給已存在變量取了?個別名&#xff0c;編譯器不會為引用變量開辟內存空間&#xff0c;它和它引用的變量共用同?塊內存空間。比如四大名著中林沖&#xff0c;他有一個外號叫豹子頭&#xff0c;類比到C里就…

【從0-1的HTML】第1篇:HTML簡介

1 HTML簡介 HTML是用來描述網頁的一種語言,是超文本標記語言的縮寫(Hyper Text Markup Language),不屬于編程語言的范疇&#xff0c;屬于一種標記語言。 標記語言使用一套標記標簽(Markup tag)&#xff0c;又稱為標簽,HTML就是使用標記標簽來描述網頁。 1.2 HTML標簽 1、HTM…

vue+cesium示例:地形開挖(附源碼下載)

基于cesium和vue繪制多邊形實現地形開挖效果&#xff0c;適合學習Cesium與前端框架結合開發3D可視化項目。 demo源碼運行環境以及配置 運行環境&#xff1a;依賴Node安裝環境&#xff0c;demo本地Node版本:推薦v18。 運行工具&#xff1a;vscode或者其他工具。 配置方式&#x…