首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 讀取加密配置:繼承 PropertyPlaceholderConfigurer 實現敏感屬性解密

     編輯:Java 綜合教學

Spring 讀取加密配置:繼承 PropertyPlaceholderConfigurer 實現敏感屬性解密

生產環境嚴禁在配置文件明文存儲資料庫密碼等敏感資訊。Spring 提供 PropertyPlaceholderConfigurer 擴展點,透過重寫 convertProperty 方法,可在屬性注入前自動解密,實現「配置文件存密文、運行時用明文」的安全目標。

1. 核心思路

  1. 配置文件中敏感屬性(如 jdbc.password)存儲 AES 加密後的密文
  2. 自定義 EncryptPropertyPlaceholderConfigurer 繼承 PropertyPlaceholderConfigurer
  3. 重寫 convertProperty(String propertyName, String propertyValue):若屬性名在加密清單中,調用 AES 解密並返回明文;否則返回原值
  4. Spring 載入屬性時自動調用該方法,完成透明解密

2. 實現代碼

public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
    // 需解密的屬性名清單
    private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};
    // AES 密鑰(16 位或 16 倍數)
    private String code = "gzxcxxxtgcyxgs01";

    @Override
    protected String convertProperty(String propertyName, String propertyValue) {
        if (isEncryptProp(propertyName)) {
            try {
                String decrypted = AESEncryptor.decrypt(code, propertyValue);
                return decrypted.isEmpty() ? propertyValue : decrypted;
            } catch (Exception e) {
                e.printStackTrace();
                return propertyValue; // 解密失敗回退原值
            }
        }
        return propertyValue;
    }

    private boolean isEncryptProp(String name) {
        for (String encryptName : encryptPropNames) {
            if (encryptName.equals(name)) return true;
        }
        return false;
    }
}

3. AES 加密工具類(略)

需提供 AESEncryptor.encrypt(key, plaintext) 與 decrypt(key, ciphertext) 靜態方法。密鑰長度必須為 16/24/32 位元組(AES-128/192/256)。

4. Spring XML 配置

<bean class="com.example.common.web.EncryptPropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
    <property name="locations">
        <list>
            <value>classpath*:/application.properties</value>
        </list>
    </property>
</bean>

替換原有的 <context:property-placeholder>。

5. 生成密文並回填配置

// 測試生成密文
String key = "1234567887654321"; // 16 位
String plain = "123456";
String cipher = AESEncryptor.encrypt(key, plain); // 如:N!Kk8dwLm0z7hlGkq2dbdQ==
System.out.println(cipher);

將密文寫入 application.properties:

jdbc.username=admin
jdbc.password=N!Kk8dwLm0z7hlGkq2dbdQ==

6. 注意事項

  • ✅ 密鑰管理:密鑰不應硬編碼在代碼中,建議從環境變數、配置中心、密鑰管理服務(KMS)讀取
  • ✅ 算法選擇:AES 屬對稱加密,若需更高安全性可考慮 RSA 非對稱加密(公鑰加密、私鑰解密)
  • ✅ Spring Boot 專案:改用 EnvironmentPostProcessor 或 PropertySourceLoader 實現同樣效果
  • ⚠️ 此方案屬「靜態加密」,無法防護運行時內存傾印攻擊,高安全等級系統需結合 Vault、Sealed Secrets 等方案

透過繼承 PropertyPlaceholderConfigurer,以極低侵入性實現配置文件敏感字段加密,是 Spring 專案落地安全合規的常用手段。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved