源本科技 | 码上会

Spring Boot 敏感信息加密

2026/04/01
3
0

引言

配置文件的安全管理是企业级应用等保合规、数据安全的核心环节。 此前我们学习的配置引用、多环境管理等均为 SpringBoot 原生能力;而敏感配置加密并非框架自带功能,却是生产环境必备能力


为什么需要加密

配置文件中明文存储敏感数据是高危安全漏洞

  • 数据库账号密码泄露 → 数据被窃取 / 篡改

  • 第三方服务密钥泄露 → 资产损失

  • 生产环境配置提交到 Git → 永久泄露无法挽回

企业级规范:所有敏感配置必须加密存储,解密密钥(盐值)绝不硬编码在配置文件中。


环境准备

技术栈

版本要求

Spring Boot

3.x

JDK

17 及以上

Maven

3.8.6 及以上

Jasypt

3.0.6(适配 Spring Boot 3)


基础准备

我们先编写明文配置,并通过单元测试读取配置,作为基准测试。

1. 编写配置

src/main/resources/application.yml

# 明文敏感配置(生产环境禁止使用)
datasource:
  username: root
  password: 123456

2. 单元测试

SpringBoot 3 完全弃用 JUnit 4,必须使用 JUnit 5 (Jupiter) 编写测试:

package com.lusifer.boot;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@Slf4j
@SpringBootTest
public class PropertiesTest {

    // 读取明文配置
    @Value("${datasource.password}")
    private String password;

    @Test
    public void testReadPlainText() {
        log.info("明文密码:{}", password);
    }
}

3. 测试结果

执行测试,控制台输出:

明文密码:123456

集成 Jasypt

Jasypt 是 Java 生态最主流的配置加密库,3.0.6 版本正式适配 Spring Boot 3

引入依赖

修改 pom.xml,引入 starter 启动器 加密插件

<dependencies>
    <!-- SpringBoot 3 Web依赖(基础依赖) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Jasypt 适配 SpringBoot 3 核心依赖 -->
    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>3.0.6</version>
    </dependency>

    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- SpringBoot 3 打包插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <!-- Jasypt Maven加密插件(批量加密配置) -->
        <plugin>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-maven-plugin</artifactId>
            <version>3.0.6</version>
        </plugin>
    </plugins>
</build>

企业级加密

Jasypt 提供标准语法:

  • DEC(明文):待加密的内容

  • ENC(密文):已加密的内容(框架自动解密)

1. 修改配置文件

# 用 DEC() 包裹需要加密的敏感信息
datasource:
  username: root
  password: DEC(123456)

2. 生成加密盐值(密钥)

盐值是解密的核心密钥,必须自定义、复杂度高、绝不泄露。 示例盐值:Sb3#Jasypt@2026!Secure(生产环境请自行生成随机字符串)

3. 执行加密命令

必须在终端执行,不要在 IDEA 直接运行

mvn jasypt:encrypt -Djasypt.encryptor.password=Sb3#Jasypt@2026!Secure

执行成功后,配置文件会自动替换

datasource:
  username: root
  password: ENC(5smCk9sZJkL9X2bP8aQ7rT4yU1iO3pS5dF8gH0jK2lZ4xV6bN8mQ0wE2rT1yU3)

Jasypt 核心配置

application.yml 中添加 Jasypt 配置,适配 SpringBoot 3 + JDK17

# Jasypt 加密配置(SpringBoot 3 兼容版)
jasypt:
  encryptor:
    # 加密算法(JDK17默认支持,高安全性)
    algorithm: PBEWITHHMACSHA512ANDAES_256
    # 随机向量生成器(解决SB3兼容问题,必加)
    iv-generator-classname: org.jasypt.iv.RandomIvGenerator
    # 密文标识前缀/后缀
    property:
      prefix: ENC(
      suffix: )

# 加密后的敏感配置
datasource:
  username: root
  password: ENC(5smCk9sZJkL9X2bP8aQ7rT4yU1iO3pS5dF8gH0jK2lZ4xV6bN8mQ0wE2rT1yU3)

推荐企业级盐值配置

优先级从高到低

启动命令参数(推荐)

# Jar 包启动时传入盐值
java -jar app.jar --jasypt.encryptor.password=Sb3#Jasypt@2026!Secure

环境变量

# Linux/Mac
export JASYPT_ENCRYPTOR_PASSWORD=Sb3#Jasypt@2026!Secure

# Windows
set JASYPT_ENCRYPTOR_PASSWORD=Sb3#Jasypt@2026!Secure

配置中心

Nacos/Apollo

将盐值托管在配置中心,配置文件不存储任何密钥信息。


代码手动加密/解密

除了 Maven 插件,我们可以编写工具类手动加密,方便开发调试:

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.iv.RandomIvGenerator;

public class JasyptUtils {
    // 盐值
    private static final String SALT = "Sb3#Jasypt@2026!Secure";

    /**
     * 加密
     */
    public static String encrypt(String plainText) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        encryptor.setPassword(SALT);
        encryptor.setIvGenerator(new RandomIvGenerator());
        return encryptor.encrypt(plainText);
    }

    /**
     * 解密
     */
    public static String decrypt(String cipherText) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        encryptor.setPassword(SALT);
        encryptor.setIvGenerator(new RandomIvGenerator());
        return encryptor.decrypt(cipherText);
    }

    public static void main(String[] args) {
        System.out.println("加密后:" + encrypt("123456"));
        System.out.println("解密后:" + decrypt("加密后的密文"));
    }
}

测试验证:自动解密

直接运行之前的 JUnit 5 测试类,无需修改代码:

@Slf4j
@SpringBootTest
public class PropertiesTest {
    @Value("${datasource.password}")
    private String password;

    @Test
    public void testReadEncryptedText() {
        // Jasypt自动解密密文
        log.info("解密后密码:{}", password);
    }
}

测试结果

解密后密码:123456

证明密文已被框架自动解密,业务代码无任何侵入!