最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實現(xiàn)敏感配置信息加密與解密

 更新時間:2025年07月08日 10:29:37   作者:風象南  
SpringBoot支持多種配置加載方式,不管用哪種方式,敏感信息(比如數(shù)據(jù)庫密碼、Redis密碼、第三方API密鑰)如果明文存儲,都會有泄露風險,下面我們就來聊聊如何對敏感配置信息加密與解密吧

一、為什么要加密配置?

先說說SpringBoot的配置加載機制。我們知道,SpringBoot支持多種配置加載方式,優(yōu)先級從高到低大概是:

  • 命令行參數(shù)
  • 環(huán)境變量
  • application-{profile}.yml
  • application.yml
  • @ConfigurationProperties注解

不管用哪種方式,敏感信息(比如數(shù)據(jù)庫密碼、Redis密碼、第三方API密鑰)如果明文存儲,都會有泄露風險:

開發(fā)環(huán)境:本地配置文件可能被傳到Git 測試環(huán)境:測試服務器可能被非授權(quán)訪問 生產(chǎn)環(huán)境:配置文件權(quán)限管理不當,被運維人員誤看

更重要的是,《網(wǎng)絡安全法》明確要求對敏感信息進行加密存儲。去年某銀行就因為數(shù)據(jù)庫密碼明文存儲被罰款200萬。

所以,給配置文件加密不是選擇題,是必答題。

二、方案一:Jasypt集成(推薦)

Jasypt是SpringBoot生態(tài)中相對成熟的配置加密工具,開箱即用,配置簡單。

1. 添加依賴

添加Jasypt依賴

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>

2. 配置加密密鑰

application.yml中添加Jasypt配置:

jasypt:
  encryptor:
    password: ${ENCRYPT_KEY}  # 密鑰從環(huán)境變量獲取
    algorithm: PBEWithHMACSHA512ANDAES_256  # 推薦使用強加密算法
    iv-generator-classname: org.jasypt.iv.RandomIvGenerator

劃重點:密鑰千萬不要寫在配置文件里!這里用環(huán)境變量${ENCRYPT_KEY},Docker部署時通過-e ENCRYPT_KEY=xxx傳入。

3. 加密敏感配置

用Jasypt提供的命令行工具加密明文密碼:

# 下載jasypt-cli包
wget https://github.com/jasypt/jasypt/releases/download/jasypt-1.9.3/jasypt-1.9.3-dist.zip
unzip jasypt-1.9.3-dist.zip

# 執(zhí)行加密命令(密鑰用你的實際密鑰替換)
java -cp jasypt-1.9.3/lib/jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="你的明文密碼" password=你的密鑰(32字節(jié)) algorithm=PBEWithHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator

執(zhí)行后會輸出加密后的密文,類似這樣:

----ENVIRONMENT-----------------
Runtime: OpenJDK 64-Bit Server VM 11.0.18+10

----ARGUMENTS-------------------
input: 你的明文密碼
password: 你的密鑰
algorithm: PBEWithHMACSHA512ANDAES_256

----OUTPUT----------------------
加密后的密文

4. 在配置文件中使用密文

把加密后的密文用ENC()包裹,放到配置文件里:

spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/order_db
    username: root
    password: ENC(加密后的密文)  # 用ENC()包裹

5. 啟動應用

啟動時傳入密鑰:

java -jar app.jar -Djasypt.encryptor.password=你的密鑰
# 或者用環(huán)境變量
ENCRYPT_KEY=你的密鑰 
java -jar app.jar

三、方案二:自定義加密解密(適合有特殊需求)

如果Jasypt滿足不了你的需求(比如要對接企業(yè)內(nèi)部的密鑰管理系統(tǒng)),可以自己實現(xiàn)加密解密邏輯。

比如,某些時候項目需要用國密算法SM4,Jasypt不支持,就需要自定義個解密處理器。

1. 實現(xiàn)思路

SpringBoot啟動時會加載配置文件,我們可以通過自定義PropertySource,在配置被讀取前進行解密。

2. 代碼實現(xiàn)

第一步:創(chuàng)建加密工具類

package com.example.config.encrypt;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.util.Base64;

/**
 * 國密SM4加密工具類
 * 依賴bcprov-jdk15on
 */
public class SM4Utils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    
    private static final String ALGORITHM_NAME = "SM4";
    private static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
    private SecretKeySpec secretKeySpec;
    private Cipher cipher;

    public SM4Utils(String key) {
        try {
            secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM_NAME);
            cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, "BC");
        } catch (Exception e) {
            throw new RuntimeException("初始化SM4加密工具失敗", e);
        }
    }

    // 加密
    public String encrypt(String plainText) {
        try {
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] encrypted = cipher.doFinal(plainText.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("SM4加密失敗", e);
        }
    }

    // 解密
    public String decrypt(String cipherText) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));
            return new String(decrypted);
        } catch (Exception e) {
            throw new RuntimeException("SM4解密失敗", e);
        }
    }
}

第二步:創(chuàng)建自定義PropertySource

package com.example.config.encrypt;

import org.springframework.core.env.PropertySource;

/**
 * 自定義加密配置源
 * 解密以"sm4:"開頭的配置項
 */
public class Sm4EncryptedPropertySource extends PropertySource<Object> {
    private final PropertySource<?> source;
    private final SM4Utils sm4Utils;

    public Sm4EncryptedPropertySource(String name, PropertySource<?> source, String key) {
        super(name);
        this.source = source;
        this.sm4Utils = new SM4Utils(key);
    }

    @Override
    public Object getProperty(String name) {
        Object value = source.getProperty(name);
        if (value instanceof String) {
            String strValue = (String) value;
            // 解密以"sm4:"開頭的配置
            if (strValue.startsWith("sm4:")) {
                String cipherText = strValue.substring(4);
                return sm4Utils.decrypt(cipherText);
            }
        }
        return value;
    }
}

第三步:注冊PropertySource

package com.example.config.encrypt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

/**
 * 環(huán)境后置處理器,注冊自定義PropertySource
 */
public class EncryptedEnvironmentPostProcessor implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        MutablePropertySources propertySources = environment.getPropertySources();
        
        // 從環(huán)境變量獲取SM4密鑰
        String sm4Key = environment.getProperty("SM4_KEY");
        if (sm4Key == null) {
            throw new RuntimeException("環(huán)境變量SM4_KEY未配置");
        }
        
        // 遍歷所有PropertySource,包裝需要解密的配置
        for (PropertySource<?> source : propertySources) {
            if (source.getName().contains("application.yaml")) {
                propertySources.replace(source.getName(), 
                    new Sm4EncryptedPropertySource(source.getName(), source, sm4Key));
            }
        }
    }
}

第四步:配置spring.factories

src/main/resources/META-INF/spring.factories中注冊后置處理器:

org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.config.encrypt.EncryptedEnvironmentPostProcessor

3. 使用方式

在配置文件中用sm4:前綴標識需要加密的配置:

spring:
  datasource:
    password: sm4:加密后的密文  # 用SM4加密

啟動時傳入密鑰:

SM4_KEY=你的密鑰 
java -jar app.jar

適用場景

  • 需要更靈活的自定義敏感數(shù)據(jù)加解密邏輯
  • 需要對接企業(yè)內(nèi)部密鑰管理系統(tǒng)(如從數(shù)據(jù)庫/接口獲取密鑰)
  • 需要更細粒度的解密控制(如按配置項類型解密)

四、從開發(fā)到生產(chǎn)的完整流程

1. 開發(fā)環(huán)境

  • 用Jasypt加密,密鑰存在本地環(huán)境變量
  • IDEA配置Run Configuration,自動注入密鑰
  • Gitignore過濾所有包含密鑰的配置文件

2. 測試環(huán)境

  • Jenkins Pipeline從憑據(jù)管理獲取密鑰
  • 構(gòu)建時自動加密配置文件
  • 部署時通過環(huán)境變量注入密鑰

3. 生產(chǎn)環(huán)境

  • 密鑰可以存儲在阿里云KMS
  • 應用啟動時通過IAM角色獲取密鑰
  • 配置文件通過Ansible或其他方式統(tǒng)一分發(fā)

4. 驗證方法

部署后一定要驗證配置是否解密成功,可以寫個簡單的接口:

@RestController
public class ConfigTestController {
    @Value("${spring.datasource.password}")
    private String dbPassword;

    @GetMapping("/test/config")
    public String testConfig() {
        // 打印脫敏后的密碼(只顯示前3位和后3位)
        if (dbPassword.length() > 6) {
            return "密碼解密成功:" + dbPassword.substring(0, 3) + "******" + dbPassword.substring(dbPassword.length() - 3);
        }
        return "密碼解密成功";
    }
}

五、總結(jié)

  • 密鑰管理:密鑰必須與配置文件分離,優(yōu)先用環(huán)境變量或?qū)S妹荑€管理服務(如阿里云KMS)
  • 算法選擇:優(yōu)先使用強加密算法(如AES-256、SM4),避免MD5、DES等弱算法
  • 多環(huán)境隔離:開發(fā)/測試/生產(chǎn)環(huán)境使用不同密鑰,定期輪換
  • 權(quán)限控制:配置文件權(quán)限設為600,僅應用進程可讀寫
  • 審計日志:記錄配置解密操作,方便追溯

最后提醒一句:配置加密不是銀彈,還需要配合代碼審計、服務器安全加固等措施,才能真正保障系統(tǒng)安全。

到此這篇關(guān)于SpringBoot實現(xiàn)敏感配置信息加密與解密的文章就介紹到這了,更多相關(guān)SpringBoot敏感信息加解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PowerJob的DesignateServer工作流程源碼解讀

    PowerJob的DesignateServer工作流程源碼解讀

    這篇文章主要介紹了PowerJob的DesignateServer工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • java檢測一個字符串是否是時間格式

    java檢測一個字符串是否是時間格式

    這篇文章主要為大家詳細介紹了一個Java方法isValidDate,用于驗證字符串是否符合24小時制時間格式"HH:mm",文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2026-03-03
  • Java 網(wǎng)絡編程socket編程等詳解

    Java 網(wǎng)絡編程socket編程等詳解

    本篇文章主要介紹了java網(wǎng)絡編程中的類的方法以及實例,需要的朋友可以參考下
    2017-04-04
  • 如何提高java代碼的重用性

    如何提高java代碼的重用性

    在本篇文章中小編給各位分享了關(guān)于如何提高java代碼的重用性的相關(guān)知識點內(nèi)容,有需要的朋友們參考下。
    2019-07-07
  • SpringBoot嵌入式Web容器原理與使用介紹

    SpringBoot嵌入式Web容器原理與使用介紹

    Web開發(fā)的核心內(nèi)容主要包括內(nèi)嵌的Servlet容器和SpringMVCSpringBoot使用起來非常簡潔,大部分配置都有SpringBoot自動裝配,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-10-10
  • Java中LinkedList數(shù)據(jù)結(jié)構(gòu)的詳細介紹

    Java中LinkedList數(shù)據(jù)結(jié)構(gòu)的詳細介紹

    這篇文章主要介紹了Java中LinkedList,Linked List 是 java.util 包中 Collection 框架的一部分,文中提供了詳細的代碼說明,需要的朋友可以參考下
    2023-05-05
  • java socket實現(xiàn)聊天室 java實現(xiàn)多人聊天功能

    java socket實現(xiàn)聊天室 java實現(xiàn)多人聊天功能

    這篇文章主要為大家詳細介紹了java socket實現(xiàn)聊天室,java實現(xiàn)多人聊天功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 基于jfreechart生成曲線、柱狀等圖片并展示到JSP

    基于jfreechart生成曲線、柱狀等圖片并展示到JSP

    這篇文章主要介紹了基于jfreechart生成曲線、柱狀等圖片并展示到JSP,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot異步調(diào)用相同類的解決方案

    SpringBoot異步調(diào)用相同類的解決方案

    在SpringBoot中,同一個類中調(diào)用帶有@Async注解的方法時,異步調(diào)用會失效,因為直接通過this調(diào)用方法時,并沒有通過Spring的代理對象,下面給大家分享SpringBoot異步調(diào)用相同類的解決方案,感興趣的朋友一起看看吧
    2025-02-02
  • Java分布式鎖由淺入深介紹

    Java分布式鎖由淺入深介紹

    這篇文章主要介紹了Java分布式鎖,數(shù)據(jù)庫實現(xiàn)分布式鎖方式比較多,如悲觀鎖(查詢時增加for?update)、樂觀鎖(通過version字段)、增加一個表記錄鎖信息等。因為依賴于數(shù)據(jù)庫,比較好理解,但是也存在一些問題
    2023-03-03

最新評論

石阡县| 邢台市| 洪泽县| 阿瓦提县| 高台县| 东乡| 米林县| 泽普县| 获嘉县| 林西县| 平顶山市| 广平县| 资源县| 千阳县| 司法| 永昌县| 马龙县| 象山县| 鄂尔多斯市| 垦利县| 山东| 洛隆县| 滦南县| 湖北省| 闽侯县| 抚顺市| 岫岩| 科尔| 三亚市| 大同市| 濉溪县| 澎湖县| 寻乌县| 垫江县| 海兴县| 略阳县| 昌乐县| 天台县| 临江市| 来宾市| 兰溪市|