詹学伟
詹学伟
Published on 2025-04-30 / 12 Visits
1
0

SpringBoot中使用jasypt对配置文件敏感数据进行加密

说明:在日常开发中,我们经常会在 yml 配置文件中存放一些敏感数据,例如数据库的用户名、密码,以及第三方应用的密钥等。然而,这些信息如果直接以明文形式存储在配置文件中,会带来严重的安全隐患。为了提升数据安全性,今天我将为大家介绍如何借助 jasypt 工具,实现对 yml 文件中敏感信息的加密处理。

一、JASYPT说明

1、核心原理概述

jasypt-spring-boot-starter 通过注册一个 ‌Spring 后处理器‌(BeanPostProcessor),在 Spring 环境初始化时对所有 PropertySource 对象进行修饰,自动识别并解密加密属性。
其核心流程包括:

  • 属性拦截‌:在 Spring Boot 启动阶段,拦截所有配置源(如 application.yml、环境变量等)。

  • 动态解密‌:检测到以 ENC(加密字符串) 格式包裹的属性值时,使用配置的加密算法和密钥进行解密。

  • 透明集成‌:解密后的值直接替换原始加密值,对业务代码无侵入。

2、关键实现细节

(1) 自动装配机制‌

  • 通过 @EnableAutoConfiguration@SpringBootApplication 触发自动配置,加载 JasyptSpringBootAutoConfiguration 类。

  • 该配置类注册了 EncryptablePropertySourcePostProcessor,负责处理所有 PropertySource

‌(2) 加解密流程‌

  • 加密密钥配置‌:通过 jasypt.encryptor.password 指定密钥(建议通过环境变量注入而非硬编码)。

  • 算法支持‌:默认使用 PBEWithMD5AndDES,也支持 AES、RSA 等算法。

  • 属性标识‌:加密值需包裹在 ENC() 中(如 password: ENC(加密字符串))。

‌(3) 安全增强‌

  • 支持 ‌加密密钥的二次加密‌(如通过环境变量存储密钥),避免密钥硬编码风险。

  • 与 Spring Cloud 配置中心兼容,可结合配置中心的加解密功能

二、实战案例

1.添加pom依赖

        <!-- 必须使用2.x版本兼容SpringBoot 2.3 -->
        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>2.1.2</version> <!-- 专门适配2.3.x的版本 -->
        </dependency>

2.添加配置文件

# 加密配置
jasypt:
  encryptor:
    password: xxxxxx  # 加密密钥(生产环境应通过环境变量传递)
    algorithm: PBEWithMD5AndDES # SpringBoot 2.3兼容的算法
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

3.编写工具类

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;

public class JasyptUtils {
    
    private static final String ALGORITHM = "PBEWithMD5AndDES";
    private static final String PASSWORD = "xxxxxx";

    public static String encrypt(String input) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(PASSWORD);
        encryptor.setAlgorithm(ALGORITHM);
        return encryptor.encrypt(input);
    }

    public static String decrypt(String encrypted) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(PASSWORD);
        encryptor.setAlgorithm(ALGORITHM);
        return encryptor.decrypt(encrypted);
    }

    public static void main(String[] args) {
        String original = "abc123";
        String encrypted = encrypt(original);
        System.out.println("加密结果: " + encrypted);
        System.out.println("解密验证: " + decrypt(encrypted));
    }
}

4.修改敏感配置

spring:
  datasource:
    dynamic:
      primary: master
      datasource:
        # 主库数据源
        master:
          url: jdbc:mysql://10.18.23.37:3306/cost?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
          username: ENC(3ai3Q1+VUsmdOKUPTczr/A==)
          password: ENC(Bfr9hahmv1YdHExS/StpTEHeRZ32pgMW)
          driverClassName: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
        slave:
          url: jdbc:mysql://10.18.23.37:3306/cost_ods?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
          username: ENC(3ai3Q1+VUsmdOKUPTczr/A==)
          password: ENC(Bfr9hahmv1YdHExS/StpTEHeRZ32pgMW)
          driverClassName: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
    druid:
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 60000
      test-while-idle: true
      test-on-borrow: true
      test-on-return: false
      validation-query: SELECT 1
      initial-size: 5
      min-idle: 5
      max-active: 20


Comment