当前位置: 首页 > news >正文

Jasypt 与 Spring Boot 集成文档

Jasypt 与 Spring Boot 集成文档

目录

  1. 简介
  2. 版本说明
  3. 快速开始
    • 添加依赖
    • 配置加密密钥
    • 加密配置文件
  4. 高级配置
    • 自定义加密算法
    • 多环境配置
  5. 最佳实践
  6. 常见问题
  7. 参考资料

简介

Jasypt 是一个简单易用的 Java 加密库,支持与 Spring Boot 无缝集成。通过 Jasypt,可以轻松加密和解密 Spring Boot 配置文件中的敏感信息(如数据库密码、API 密钥等),从而提高应用的安全性。


版本说明

支持版本

  • JDK 版本:JDK 1.8 及以上。
  • Spring Boot 版本:Spring Boot 2.x(推荐 2.5.6 及以上)。
  • Jasypt 版本jasypt-spring-boot-starter 3.x(推荐 3.0.5 及以上)。

版本区间建议

组件推荐版本备注
JDK1.8 或 11JDK 1.8 是主流选择,JDK 11 支持长期维护。
Spring Boot2.5.6 - 2.7.xSpring Boot 2.x 是稳定版本。
Jasypt3.0.5最新稳定版本,兼容 Spring Boot 2.x。

快速开始

添加依赖

在 Spring Boot 项目中,添加 jasypt-spring-boot-starter 依赖:

Maven

pom.xml 中添加以下依赖:

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

build.gradle 中添加以下依赖:

implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'

配置加密密钥

Jasypt 需要一个加密密钥来加密和解密数据。密钥可以通过以下方式配置:

1. 在 application.yml 中配置(这个写在数据库配置的上面)
jasypt:
  encryptor:
    # 盐值
    password: vilasto
    # 指定加密方式
    algorithm: PBEWithSHA1AndRC2_40
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    property:
      # 标识为加密属性的前缀
      prefix: ENC(
      # 标识为加密属性的后缀
      suffix: )

加密配置文件

1. 加密敏感数据

使用 Jasypt 提供的工具加密敏感数据。以下是一个示例:

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentPBEConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JasyptUtil {
    private static final Logger logger = LoggerFactory.getLogger(JasyptUtil.class);

    /**
     * PBE 算法
     */
    public static final String PBE_ALGORITHMS_MD5_DES = "PBEWithMD5AndDES";
    public static final String PBE_ALGORITHMS_MD5_TRIPLEDES = "PBEWithMD5AndTripleDES";
    public static final String PBE_ALGORITHMS_SHA1_DE_SEDE = "PBEWithSHA1AndDESede";
    public static final String PBE_ALGORITHMS_SHA1_RC2_40 = "PBEWithSHA1AndRC2_40";


    /**
     * Jasypt 加密
     *
     * @param encryptedStr 加密字符串
     * @param algorithm    加密算法
     * @param password     盐值
     * @return
     */
    public static String encrypt(String encryptedStr, String algorithm, String password) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

        // 指定加密算法
        config.setAlgorithm(algorithm);
        // 加密盐值
        config.setPassword(password);
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        encryptor.setConfig(config);

        // 加密
        return encryptor.encrypt(encryptedStr);
    }


    /**
     * Jasypt 解密
     *
     * @param decryptStr 解密字符串
     * @param algorithm  指定解密算法:解密算法要与加密算法一一对应
     * @param password   盐值
     * @return
     */
    public static String decrypt(String decryptStr, String algorithm, String password) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        EnvironmentPBEConfig config = new EnvironmentPBEConfig();

        // 指定解密算法:解密算法要与加密算法一一对应
        config.setAlgorithm(algorithm);
        // 加密秘钥
        config.setPassword(password);
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        encryptor.setConfig(config);

        // 解密
        return encryptor.decrypt(decryptStr);
    }

    public static void main(String[] args) {
        // 数据库明文密码
        String encryptedStr = "123456";
        // 加密算法-与application.yml配置一致
        String algorithm = PBE_ALGORITHMS_SHA1_RC2_40;
        //盐值-与application.yml配置一致
        String password = "vilasto"; 

        String str = JasyptUtil.encrypt(encryptedStr, algorithm, password);
        //实际加密字符串中不包含ENC(),但是application.yml需要,打印添加了ENC()防止application.yml粘贴遗忘,
        logger.info("加密后的字符串: {}", "ENC(" + str + ")");
        logger.info("解密后的字符串: {}", JasyptUtil.decrypt(str, algorithm, password));
    }
}
2. 在配置文件中使用加密值

将加密后的值用 ENC() 包裹,放入 application.yml 中:

app:
  username: admin
  password: ENC(这里面写加密字符串,现在控制台打印带了ENC()可以直接复制粘贴)

高级配置

自定义加密算法

为了进一步防止密码泄露,我们可以自定义加密规则。

自定义加密规则非常简单,只需要提供自定义的加密器配置类,然后通过jasypt.encryptor.bean配置指定加密配置类即可。

/**
 * 自定义加密器
 */
public class MyStringEncryptor implements StringEncryptor {
 
    /**
     * 加解密PBE 算法
     */
    public static final String PBE_ALGORITHMS_MD5_DES = "PBEWithMD5AndDES";
    public static final String PBE_ALGORITHMS_MD5_TRIPLEDES = "PBEWithMD5AndTripleDES";
    public static final String PBE_ALGORITHMS_SHA1_DE_SEDE = "PBEWithSHA1AndDESede";
    public static final String PBE_ALGORITHMS_SHA1_RC2_40 = "PBEWithSHA1AndRC2_40";
 
    /**
     * 加解密盐值
     */
    private String password;
    /**
     * 加解密算法
     */
    private String algorithm = PBE_ALGORITHMS_MD5_DES;
 
    public MyStringEncryptor(String password) {
        this.password = password;
    }
 
    public MyStringEncryptor(String password, String algorithm) {
        this.password = password;
        this.algorithm = algorithm;
    }
 
    @Override
    public String encrypt(String message) {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 加解密盐值
        encryptor.setConfig(getConfig(this.password));
        return encryptor.encrypt(message);
    }
 
    @Override
    public String decrypt(String encryptedMessage) {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(getConfig(this.password));
        return encryptor.decrypt(encryptedMessage);
    }
 
    public SimpleStringPBEConfig getConfig(String password) {
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        // 加密盐值
        config.setPassword(password);
        // 加解密算法
        config.setAlgorithm(PBE_ALGORITHMS_MD5_DES);
        // 设置密钥获取迭代次数
        config.setKeyObtentionIterations(1000);
        // 线程池大小:默认1
        config.setPoolSize(1);
        // 盐值生成器className
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        //  iv(initialization vector,初始化向量) 生成器className
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        // 设置字符串输出类型
        config.setStringOutputType("base64");
        return config;
    }
}

将自定义加密器添加到 Spring IoC 容器中

@Configuration
public class JasyptConfig {
    /**
     * 加解密盐值
     */
    @Value("${jasypt.encryptor.password}")
    private String password;
 
    // @Bean("jasyptStringEncryptor")
    @Bean("myStringEncryptor")
    public StringEncryptor myStringEncryptor() {
        return new MyStringEncryptor(password);
    }
}
application.yml 中配置
jasypt:
  encryptor:
    # 指定加解密在spring ioc容器中bean的名称,默认 jasyptStringEncryptor
    bean: myStringEncryptor
    # 盐值
    password: vilasto

注意:Jasypt默认加解密器beanName为jasyptStringEncryptor,如果不想在配置文件中指定自定义加密器名称,需将自定义加密器beanName设置为jasyptStringEncryptor,否则将不生效。

加密盐值通过环境变量指定

  • 方式一:直接作为程序启动时的命令行参数
java -jar app.jar --jasypt.encryptor.password=vilasto
  • 方式二:直接作为程序启动时的应用环境变量
java -Djasypt.encryptor.password=vilasto -jar app.jar
  • 方式三:直接作为系统环境变量
# 1. 设置系统环境变量 JASYPT_ENCRYPTOR_PASSWORD = vilasto
 
# 2. Spring Boot的项目配置文件指定系统环境变量:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}

多环境配

在不同的环境(如开发、测试、生产)中,可以使用不同的加密密钥和配置文件。

1. 创建环境配置文件
  • application-dev.yml(开发环境)
  • application-prod.yml(生产环境)
2. 配置环境变量

在启动应用时,指定激活的环境:

java -jar your-application.jar --spring.profiles.active=prod
3. 环境配置文件示例

application-prod.yml

jasypt:
  encryptor:
    password: prod-secret-key

app:
  password: ENC(9Xy7C5z8eX0ZQzKz5o1o2w==)

最佳实践

  1. 密钥管理

    • 不要将密钥硬编码在代码中。
    • 使用环境变量或密钥管理服务(如 AWS KMS、HashiCorp Vault)传递密钥。
  2. 配置文件加密

    • 对敏感配置(如数据库密码、API 密钥)进行加密。
  3. 日志脱敏

    • 避免在日志中输出敏感信息的明文。
  4. 定期更换密钥

    • 定期更换加密密钥,并重新加密配置文件。

常见问题

1. 加密值无法解密

  • 检查加密密钥是否一致。
  • 检查加密算法是否一致。

2. 启动时抛出 EncryptionOperationNotPossibleException

  • 确保加密值正确包裹在 ENC() 中。
  • 确保加密密钥正确配置。

3. 多环境配置不生效

  • 检查 spring.profiles.active 是否正确设置。
  • 确保环境配置文件命名正确(如 application-prod.yml)。

参考资料

  • Jasypt 官网
  • Jasypt GitHub 仓库
  • Jasypt Spring Boot Starter GitHub 仓库

相关文章:

  • 好数——前缀和思想(题目分享)
  • 数据仓库为什么要分层
  • 计算机网络软考
  • 如何在Conda 虚拟环境中安装一个隔离的CUDA版本
  • 【AI Guide】AI面试攻略只用看这一篇就够了!力争做全网最全的AI面试攻略——大模型(二十七)多任务学习
  • 飞鱼动画笔记
  • 17.10 LangSmith Evaluation 深度实战:构建智能评估体系驱动大模型进化
  • 与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景
  • Leetcode LRU缓存
  • 嵌入式开发:傅里叶变换(5):基于STM32,实现CMSIS中的DSP库
  • C语言常见概念
  • 代码随想录算法训练营 | 图论 | DFS
  • 《几何原本》命题I.8
  • 【QGIS二次开发】地图显示与交互-01
  • 分类任务和回归任务的区别
  • 第八章 函数
  • LeetCode热题100JS(20/100)第四天|​41. 缺失的第一个正数​|​73. 矩阵置零​|​54. 螺旋矩阵​|​48. 旋转图像​
  • Arm64架构的Linux服务器安装jdk8
  • 叁[3],直线的角度问题
  • HTML-05NPM使用踩坑
  • 上海龙象建设集团公司网站/沈阳cms模板建站
  • 系统网站建设公司/小网站怎么搜关键词
  • 网站搭建多少钱徐州百都网络非常好/开网店如何运营和推广
  • 上海闵行网站建设/市场营销策划方案案例
  • 网址域名注册流程/西安seo服务商
  • 零食网站页面模板/湖南专业seo公司