前言
在SpringBoot项目开发、测试、生产全流程中,配置文件明文存储数据库账号密码、Redis密钥、第三方接口Token等敏感信息,是极大的安全漏洞。一旦源码、配置文件泄露,会直接导致数据库脱库、服务被恶意入侵,造成数据泄露、业务瘫痪等严重事故。
按照企业安全开发规范:Web应用配置文件禁止明文存储任何账号、密码、密钥等敏感数据,必须加密脱敏存储。
本文将基于开源安全框架 Jasypt,手把手实现SpringBoot配置文件敏感信息加密,详解官方推荐的三种集成方案、版本适配避坑、秘钥安全部署、自动解密取值等核心实战内容,同时搭配配置文件清理规范,全方位完成项目安全加固。

一、前置基础:配置文件安全预处理

在进行密码加密之前,首先完成配置文件规范化清理,从源头规避信息泄露风险,这是项目安全的基础操作。

1.1 清理规范

  • 删除所有废弃配置、测试注释、临时备注、被注释的无效代码;
  • 清除包含环境地址、测试账号、业务备注等敏感信息的注释;
  • 仅保留核心有效配置,精简文件结构。
    **
    1.2 清理前后对比**
    清理前(存在冗余+明文风险)
# 测试库配置-2025废弃
# spring:
#   datasource:
#     url: jdbc:mysql://localhost:3306/test
#     username: root
#     password: 123456
# 生产数据库配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/prod
    username: root
    password: admin@123456 # 生产数据库密码

清理后(干净无冗余)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/prod
    username: root
    password: admin@123456

二、Jasypt核心简介

Jasypt(Java Simplified Encryption)是一款开源、轻量的Java加密工具库,专门适配SpringBoot项目,核心作用是加密配置文件中的敏感属性,实现配置密文存储、项目启动自动解密。
官方地址:http://www.jasypt.org/
SpringBoot集成开源地址:https://github.com/ulisesbocchio/jasypt-spring-boot

2.1 核心特性

  • 无业务侵入:无需修改业务代码,仅需配置依赖和秘钥;
  • 自动加解密:项目启动自动解析密文,开发者取值无需特殊处理;
  • 随机密文特性:同一秘钥、同一明文,多次加密生成的密文不同,但均可正常解密,安全性更高;
  • 全属性适配:支持yml、properties、系统属性、环境变量、命令行参数等所有配置源加密。

2.2 固定加密格式
Jasypt规定密文必须使用 ENC(密文字符串) 格式包裹,框架会自动识别该标识并解密:

spring:
  datasource:
    password: ENC(o6L5p3ymfSMiscyR9CPio4NfGPg+W9==)
    

取值方式与普通配置完全一致,通过 @Value、@ConfigurationProperties 均可直接获取解密后的明文,无需手动解密。

三、SpringBoot三种官方集成方案

Jasypt官方提供三种适配方案,适配不同SpringBoot项目架构,覆盖绝大多数开发场景,按需选择即可。
版本适配说明:JDK8 推荐使用 2.1.2 版本;JDK9+ 推荐使用 3.x 版本,避免算法兼容报错。

3.1 方式一:自动适配(主流推荐)
适用场景:项目使用 @SpringBootApplication 或 @EnableAutoConfiguration 注解(99%的SpringBoot项目)
仅需引入starter启动器,无需额外注解,自动全局开启配置加密解密功能。
Maven依赖:

<!-- Jasypt加密工具 JDK8适配2.1.2 -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

3.2 方式二:全局手动开启
适用场景:项目无自动配置注解,需要手动全局开启加密属性

步骤1:引入基础依赖(非starter)

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

步骤2:启动类添加全局加密注解

import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
// 全局开启可加密属性配置
@EnableEncryptableProperties
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

3.3 方式三:指定配置文件加密(精准控制)

适用场景:无需全局加密,仅指定部分配置文件开启加密功能

步骤1:引入同方式二的基础依赖

步骤2:通过注解绑定指定配置文件(支持多文件、yml/properties)

import com.ulisesbocchio.jasyptspringboot.annotation.EncryptablePropertySource;
import com.ulisesbocchio.jasyptspringboot.annotation.EncryptablePropertySources;
import org.springframework.context.annotation.Configuration;

// 单配置文件加密
// @Configuration
// @EncryptablePropertySource(value = "classpath:application.yml")

// 多配置文件批量加密
@Configuration
@EncryptablePropertySources({
        @EncryptablePropertySource("classpath:application.yml"),
        @EncryptablePropertySource("classpath:dev.yml")
})
public class JasyptConfig {
}

补充:Jasypt 1.8+ 版本全面支持YAML文件加密,无需额外配置。

四、完整实战:加密生成+配置使用+取值测试

本文以最常用的方式一为例,完成全套实战操作,适配JDK8 + SpringBoot2.x。
4.1 完整项目依赖

<dependencies>
    <!-- SpringBoot Web核心 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>
    <!-- Jasypt加密工具 -->
    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>2.1.2</version>
    </dependency>
    <!-- 单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

4.2 单元测试生成密文(推荐)
编写Junit测试类,自定义秘钥,批量生成账号、密码密文,无需启动项目,高效便捷。

import org.jasypt.util.text.BasicTextEncryptor;
import org.junit.Test;

public class JasyptEncryptTest {

    // 自定义全局加密秘钥(自行修改为复杂秘钥)
    private static final String SECRET_KEY = "MyJasyptKey@2026";

    @Test
    public void encryptPwd() {
        BasicTextEncryptor encryptor = new BasicTextEncryptor();
        // 设置加密秘钥
        encryptor.setPassword(SECRET_KEY);

        // 待加密明文:数据库账号、密码
        String username = "root";
        String password = "admin@123456";

        // 执行加密
        String encUsername = encryptor.encrypt(username);
        String encPassword = encryptor.encrypt(password);

        System.out.println("账号密文:" + encUsername);
        System.out.println("密码密文:" + encPassword);
    }
}

执行测试方法,即可获取密文,每次运行密文不同,不影响解密使用。

4.3 配置文件密文替换
将生成的密文通过ENC() 包裹,替换明文配置,临时配置秘钥用于本地测试:

# 数据库加密配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/prod
    username: ENC(生成的账号密文)
    password: ENC(生成的密码密文)

# Jasypt加密秘钥(本地测试使用,生产必须删除)
jasypt:
  encryptor:
    password: MyJasyptKey@2026

4.4 配置属性自动解密取值
通过 @ConfigurationProperties 绑定配置,框架自动解密,业务层直接使用明文。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {

    // 自动解密为明文
    private String username;
    private String password;
    private String url;

    // getter/setter
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

五、生产环境高阶安全:秘钥外置部署

将秘钥写在配置文件中存在泄露风险,生产环境绝对禁止秘钥落地配置文件,必须通过启动参数动态传入,实现「密文、秘钥分离存储」。

5.1 移除配置文件秘钥
删除yml中所有 jasypt.encryptor.password 配置。

5.2 两种生产启动方式

# 方式1:命令行参数传入(常用)
java -jar project.jar --jasypt.encryptor.password=MyJasyptKey@2026

# 方式2:系统变量传入
java -Djasypt.encryptor.password=MyJasyptKey@2026 -jar project.jar

5.3 Docker/云服务器适配
容器化部署可通过环境变量传入秘钥,安全性更高:

# 设置全局环境变量
export JASYPT_ENCRYPTOR_PASSWORD=MyJasyptKey@2026
# 启动项目
java -jar project.jar

六、版本兼容报错全方位避坑

6.1 3.x版本启动报错:Failed to bind properties
报错原因:Jasypt3.0+ 默认采用 PBEWITHHMACSHA512ANDAES_256 高强度加密算法,该算法需要JDK1.9+支持,低版本JDK缺少JCE无限强度加密策略文件,导致解密失败。

6.2 两种解决方案
方案一(推荐):降级版本
JDK8 项目直接使用 2.1.2 稳定版本,无算法兼容问题。
方案二:修改加密算法
3.x版本手动指定兼容算法,关闭随机IV生成:

jasypt:
  encryptor:
    password: 自定义秘钥
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

七、常见问题汇总

解密失败:秘钥与加密时不一致、密文残缺、ENC()括号存在空格、版本算法不匹配;

  • 属性注入为空:@ConfigurationProperties注解未开启、配置前缀错误;
  • 生产秘钥不生效:未删除配置文件本地秘钥、启动参数拼写错误。

八、总结

本文完成了SpringBoot配置文件全方位安全加固,核心要点如下:

  1. 基础优化:清理配置文件冗余注释,杜绝间接信息泄露;
  2. 多方案集成:适配三种官方Jasypt集成方式,覆盖所有项目场景;
  3. 安全加密:实现敏感信息密文存储,框架自动解密,业务零侵入;
  4. 生产规范:秘钥外置部署,彻底解决秘钥泄露风险;
  5. 版本避坑:解决高低版本算法兼容问题,适配JDK8/11/17。
    该方案完全符合企业生产安全规范,是SpringBoot项目敏感配置保护的最优解。

更多推荐