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

springboot實(shí)現(xiàn)配置文件關(guān)鍵信息加解密

 更新時(shí)間:2025年05月08日 15:29:01   作者:愚公  
在項(xiàng)目配置文件中常常會(huì)配置如數(shù)據(jù)庫(kù)連接信息,redis連接信息等,連接密碼明文配置在配置文件中會(huì)很不安全,所以本文就來聊聊如何使用springboot實(shí)現(xiàn)配置文件關(guān)鍵信息加解密吧

前言

在項(xiàng)目配置文件中常常會(huì)配置如數(shù)據(jù)庫(kù)連接信息、redis連接信息,而連接密碼明文配置在配置文件中會(huì)很不安全,所以就會(huì)將密碼信息加密后放在配置文件中,在啟動(dòng)項(xiàng)目時(shí)自動(dòng)解密轉(zhuǎn)換成明文后進(jìn)行連接,防止密碼泄露。

方案

1、實(shí)現(xiàn) EnvironmentPostProcessor 接口

2、引入 jasypt-spring-boot-starter 依賴

實(shí)踐

1、第一種方案

EnvironmentPostProcessor 是 Spring Boot 提供的一個(gè)接口,用于在 Spring Boot 的 Environment 初始化完成后對(duì)其進(jìn)行進(jìn)一步的處理。它允許你在 Spring Boot 的配置加載階段動(dòng)態(tài)修改或增強(qiáng) Environment 的內(nèi)容,例如添加額外的配置源、修改屬性值等。 ### 作用和用途

EnvironmentPostProcessor 的主要作用是在 Spring Boot 的啟動(dòng)過程中,對(duì) Environment 對(duì)象進(jìn)行擴(kuò)展或修改。它通常用于以下場(chǎng)景:

  • 動(dòng)態(tài)添加配置源:例如,從遠(yuǎn)程配置中心(如 Spring Cloud Config Server、Consul 等)加載配置。
  • 修改或覆蓋配置屬性:例如,根據(jù)環(huán)境變量或命令行參數(shù)動(dòng)態(tài)調(diào)整某些配置值。
  • 解析加密的配置屬性:例如,解密配置文件中加密的敏感信息。
  • 添加自定義的配置解析邏輯:例如,支持自定義的配置文件格式或解析規(guī)則。

使用方法

實(shí)現(xiàn) EnvironmentPostProcessor 接口,并將自定義實(shí)現(xiàn)類注冊(cè)到springboot中

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定義EnvironmentPostProcessor,在spring啟動(dòng)前將遍歷配置文件中是否有加密的值,將加密的值按自定義解密工具進(jìn)行解密
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        environment.getPropertySources().forEach(propertySource -> {
            if (propertySource instanceof MapPropertySource) {
                MapPropertySource mapSource = (MapPropertySource) propertySource;
                Map<String, Object> originalSource = mapSource.getSource();

                // 創(chuàng)建新的可修改 Map 副本
                Map<String, Object> decryptedSource = new HashMap<>(originalSource);

                // 遍歷并解密值
                decryptedSource.replaceAll((key, value) -> {
                    if (value instanceof String) {
                        String strValue = (String) value;
                        if (strValue.startsWith("ENC(") && strValue.endsWith(")")) {
                            String encryptedContent = strValue.substring(4, strValue.length() - 1);
                            return AESEncryptionUtils.decrypt(encryptedContent);
                        }
                    }
                    return value;
                });

                // 用解密后的 Map 替換原 PropertySource
                environment.getPropertySources().replace(
                        mapSource.getName(),
                        new MapPropertySource(mapSource.getName(), decryptedSource)
                );
            }
        });
    }
}

注冊(cè) EnvironmentPostProcessor 實(shí)現(xiàn)類

META-INF/spring.factories 文件中注冊(cè)你的 EnvironmentPostProcessor

org.springframework.boot.env.EnvironmentPostProcessor=\
  com.example.DecryptEnvironmentPostProcessor

自定義加解密工具類

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.security.SecureRandom;

public class AESEncryptionUtils {

    private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; // 使用 CBC 模式 + PKCS5 填充
    private static final String SECRET_KEY = "oJ51lypwUNzBIFXO"; // 密鑰環(huán)境變量名稱

    /**
     * 加密明文
     * @param plaintext 待加密的明文
     * @return 格式為 "Base64(IV):Base64(密文)" 的字符串
     */
    public static String encrypt(String plaintext) {
        try {
            // 生成隨機(jī) IV
            byte[] ivBytes = new byte[16];
            SecureRandom random = new SecureRandom();
            random.nextBytes(ivBytes);
            IvParameterSpec iv = new IvParameterSpec(ivBytes);

            // 初始化加密器
            SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);

            // 執(zhí)行加密
            byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));

            // 組合 IV 和密文,用 Base64 編碼
            String ivBase64 = Base64.getEncoder().encodeToString(ivBytes);
            String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBytes);
            return ivBase64 + ":" + encryptedBase64;
        } catch (Exception e) {
            throw new RuntimeException("加密失敗", e);
        }
    }

    /**
     * 解密密文
     * @param encryptedText 格式為 "Base64(IV):Base64(密文)" 的字符串
     * @return 解密后的明文
     */
    public static String decrypt(String encryptedText) {
        try {
            // 拆分 IV 和密文
            String[] parts = encryptedText.split(":");
            if (parts.length != 2) {
                throw new IllegalArgumentException("無效的加密格式");
            }
            byte[] ivBytes = Base64.getDecoder().decode(parts[0]);
            byte[] encryptedBytes = Base64.getDecoder().decode(parts[1]);

            // 初始化解密器
            IvParameterSpec iv = new IvParameterSpec(ivBytes);
            SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

            // 執(zhí)行解密
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("解密失敗", e);
        }
    }
}

2、第二種方案

引入依賴

在項(xiàng)目的 pom.xml 文件中添加以下依賴:

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

配置 jasypt 信息

jasypt:
  encryptor:
    password: encryption-key
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

密碼加密

從 Jasypt 官方網(wǎng)站 或 Maven 中央倉(cāng)庫(kù)下載 jasypt-1.9.3.jar。

使用 Jasypt 的命令行工具對(duì)配置信息進(jìn)行加密。例如,加密數(shù)據(jù)庫(kù)密碼:

java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123456" password=encryption-key algorithm=PBEWithMD5AndDES

上述命令會(huì)輸出一個(gè)加密后的字符串,例如:

在配置文件中配置加密后的字符串:

spring:
  datasource:
    password: ENC(pxaWXichlG6mranljAUiZQ==)

在應(yīng)用啟動(dòng)時(shí),jasypt 會(huì)使用密鑰解密 ENC() 中的內(nèi)容,并將其值注入到對(duì)應(yīng)的配置屬性中。

jasypt 加解密工具類

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;

/**
 * jasypt 解密工具類
 */
public class EncryptionUtil {

    public static String encrypt(String input, String password) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(password);
        return encryptor.encrypt(input);
    }

    public static String decrypt(String encryptedValue, String password) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(password);
        return encryptor.decrypt(encryptedValue);
    }
}

補(bǔ)充

jasypt 密鑰配置到配置文件中其實(shí)也不太安全,更安全的做法是將密鑰配置到環(huán)境變量中或設(shè)置在啟動(dòng)命令中

export JASYPT_ENCRYPTOR_PASSWORD=your-encryption-key
java -jar your-application.jar --jasypt.encryptor.password=your-encryption-key

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

相關(guān)文章

  • 一文搞懂JAVA 修飾符

    一文搞懂JAVA 修飾符

    這篇文章主要介紹了JAVA 修飾符的的相關(guān)資料,文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 用Java實(shí)現(xiàn)聊天程序

    用Java實(shí)現(xiàn)聊天程序

    這篇文章主要為大家詳細(xì)介紹了用Java實(shí)現(xiàn)聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Spring?AOP中三種增強(qiáng)方式的示例詳解

    Spring?AOP中三種增強(qiáng)方式的示例詳解

    AOP?(Aspect?Orient?Programming),直譯過來就是?面向切面編程。AOP?是一種編程思想,是面向?qū)ο缶幊蹋∣OP)的一種補(bǔ)充。本文為大家介紹了Spring?AOP中三種增強(qiáng)方式,感興趣的可以了解一下
    2022-07-07
  • Java中反射詳解

    Java中反射詳解

    本文主要介紹了Java中反射的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Java中冒泡排序的原生實(shí)現(xiàn)方法(正序與逆序)

    Java中冒泡排序的原生實(shí)現(xiàn)方法(正序與逆序)

    這篇文章主要給大家介紹了關(guān)于Java中冒泡排序的原生實(shí)現(xiàn)方法(正序與逆序)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • java中的日期和時(shí)間比較大小

    java中的日期和時(shí)間比較大小

    這篇文章主要介紹了java中的日期和時(shí)間比較大小,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 詳解Java正則表達(dá)式中Pattern類和Matcher類

    詳解Java正則表達(dá)式中Pattern類和Matcher類

    java.util.regex是一個(gè)用正則表達(dá)式所訂制的模式來對(duì)字符串進(jìn)行匹配工作的類庫(kù)包。包括兩個(gè)類Pattern和Matcher Pattern,Pattern是一個(gè)正則表達(dá)式經(jīng)編譯后的表現(xiàn)模式。Matcher對(duì)象是一個(gè)狀態(tài)機(jī)器,它依據(jù)Pattern對(duì)象做為匹配模式對(duì)字符串展開匹配檢查。
    2016-12-12
  • Java實(shí)現(xiàn)圖片淡入淡出效果

    Java實(shí)現(xiàn)圖片淡入淡出效果

    在現(xiàn)代圖形用戶界面和游戲開發(fā)中,**圖片淡入淡出(Fade In/Out)**是一種常見且實(shí)用的視覺過渡效果,它可以用于啟動(dòng)畫面、場(chǎng)景切換、輪播圖、提示框彈出等場(chǎng)景,通過本項(xiàng)目,您將全面了解 Java 上實(shí)現(xiàn)淡入淡出效果的各個(gè)要點(diǎn),需要的朋友可以參考下
    2025-05-05
  • Java中保證線程順序執(zhí)行的操作代碼

    Java中保證線程順序執(zhí)行的操作代碼

    本文給大家分享一篇教程關(guān)于java線程順序執(zhí)行問題,如何保證線程的順序執(zhí)行呢?今天通過實(shí)例代碼給大家詳細(xì)講解下,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • SpringCloud使用集中配置組件Config規(guī)避信息泄露

    SpringCloud使用集中配置組件Config規(guī)避信息泄露

    項(xiàng)目應(yīng)用中,數(shù)據(jù)庫(kù)連接信息、Access-key、Secret-key等由于其及其敏感和特殊性,一旦泄露出去就很可能會(huì)使得應(yīng)用遭到黑客攻擊,例如數(shù)據(jù)庫(kù)賬號(hào)密碼泄露可能導(dǎo)致“拖庫(kù)”,甚至數(shù)據(jù)丟失。此等事件偶有發(fā)生,那么,在分布式微服務(wù)項(xiàng)目中,怎么避免這種情況呢
    2022-07-07

最新評(píng)論

兖州市| 永平县| 临湘市| 扎兰屯市| 信宜市| 城口县| 岱山县| 桦甸市| 石嘴山市| 札达县| 平凉市| 共和县| 达拉特旗| 盈江县| 来凤县| 大港区| 浦北县| 汝城县| 莱西市| 屏东市| 宁南县| 本溪市| 云安县| 泗水县| 昭觉县| 平泉县| 博罗县| 绥德县| 岱山县| 桑植县| 拉萨市| 廉江市| 吉隆县| 北京市| 霍林郭勒市| 东阳市| 海阳市| 手游| 张家界市| 积石山| 宜春市|