SpringBoot(四十一)SpringBoot集成jasypt加密、解密实现对yml配置文件中的敏感数据进行混淆

1,305 阅读5分钟

在开发中,项目中有部分敏感信息是不想被所有的开发人员看到的,比如数据库密码,以及RabbitMQ密码等。这部分信息一般都是配置在yml配置文件中的。

 

这里我们可以使用jasypt加密库对字符串进行加密。再将加密之后的数据写入yml文件中。就可以实现对yml中的敏感数据混淆的效果。

 

这里简单介绍一下jasypt库加密库:

Jasypt (Java Simplified Encryption) 是一个开源的Java库,专注于简化加解密过程,特别适合在Java应用程序中处理敏感数据,如密码、密钥或任何其他需要保护的信息。Jasypt的目标是提供一个易于使用的API,使得开发者能够轻松地集成加密功能,而不必成为加密专家。以下是Jasypt的一些关键特性及用途。

 

关键特性:

1)      文本加密与解密:Jasypt允许你加密字符串,并在需要时轻松解密回原始形式。这对于存储如数据库密码、API密钥等敏感信息非常有用。

2)      密码器支持:它支持多种加密算法(如PBEWITHMD5ANDDES、PBEWITHSHA256AND256BITAES-CBC-BC等),并允许自定义加密策略。

3)      配置文件加密:特别适用于Spring框架,Jasypt可以透明地解密在配置文件中加密的属性,比如数据库连接字符串中的密码。

4)      环境感知:可以在不同的环境中(如开发、测试、生产)使用不同的加密策略和密钥,增强安全性。

5)      无状态操作:Jasypt的加密操作不依赖于外部状态,使得它易于部署和使用。

6)      集成友好:提供了与Spring框架的紧密集成,可以通过Spring Boot Starter轻松配置和使用。

 

用途:

1)      安全存储配置信息:在配置文件中加密mysql、redis等数据库密码,防止明文泄露。

2)      应用内加密逻辑:在应用内部对敏感数据进行加解密操作,例如用户密码的存储和验证。

3)      日志安全:在记录包含敏感信息的日志前对其进行加密,确保日志安全。

4)      数据交换安全:在不同系统间交换数据时,对数据进行加密传输,保障数据传输的安全性。

 

一:添加pom依赖

<!-- 加密库       -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

 

二:添加yml依赖

jasypt:
  encryptor:
    # 盐值(这个不建议在这里配置,用户有了这个秘钥,就可以解密了)
    #password: 111
    # 指定加密方式
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    property:
      # 标识为加密属性的前缀
      prefix: ENC(
      # 标识为加密属性的后缀
      suffix: )

 

三:编写工具类

package com.modules.utils;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentPBEConfig;

public class JasyptUtil {

    /**
     * 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_DESEDE = "PBEWITHSHA1ANDDESEDE";
    public static final String PBE_ALGORITHMS_SHA1_RC2_40 = "PBEWITHSHA1ANDRC2_40";

    private JasyptUtil() {
    }

    /**
     * Jasypt 加密
     *
     * @param encryptedStr 加密字符串
     * @param password     盐值
     * @return
     */
    public static String encrypt(String encryptedStr, String password) {
        return encrypt(encryptedStr, PBE_ALGORITHMS_MD5_DES, password);
    }

    /**
     * Jasypt 加密
     *
     * @param encryptedStr 加密字符串
     * @param algorithm    加密算法
     *                     PBE ALGORITHMS: [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
     * @param password     盐值
     * @return
     */
    public static String encrypt(String encryptedStr, String algorithm, String password) {
        // StandardPBEStringEncryptor、StandardPBEBigDecimalEncryptor、StandardPBEBigIntegerEncryptor、StandardPBEByteEncryptor
        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 password   盐值
     * @return
     */
    public static String decrypt(String decryptStr, String password) {
        return decrypt(decryptStr, PBE_ALGORITHMS_MD5_DES, password);
    }

    /**
     * Jasypt 解密
     *
     * @param decryptStr 解密字符串
     * @param algorithm  指定解密算法:解密算法要与加密算法一一对应
     *                   PBE ALGORITHMS: [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
     * @param password   盐值
     * @return
     */
    public static String decrypt(String decryptStr, String algorithm, String password) {
        // StandardPBEStringEncryptor、StandardPBEBigDecimalEncryptor、StandardPBEBigIntegerEncryptor、StandardPBEByteEncryptor
        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);
    }

    /**
     * 测试加密解密
     * @param args
     */
    public static void main(String[] args) {
        // 加密字符串
        String encryptedStr = "hello world!";
        // 加密算法
        String algorithm = PBE_ALGORITHMS_MD5_DES;
        // 加密key
        String password = "1111";
        // 执行加密
        String str = JasyptUtil.encrypt(encryptedStr, algorithm, password);
        System.out.println("加密后的字符串:" + str);
        System.out.println("解密后的字符串:" + JasyptUtil.decrypt(str, algorithm, password));
    }
}

 

我这里使用代码来生成密文。代码中都有注释,参照即可。

运行代码:控制台输出:

加密后的字符串:Jdo2v6uKsNKXlZHIpTXN7smro4Nue9ws
解密后的字符串:hello world!

 

四:修改yml中对应的值

这里需要注意一下,加密后的字符串直接不能使用需要使用ENC()包裹,程序才认识。

如下所示:

spring:
  # 数据库链接
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: ENC(rIMRWOpNhTncba3VgW7iFxGVL0kDnKxW)

 

五:配置IDEA运行参数

我们在yml中没有配置jasypt的盐值(加密key)开发人员不能解密了,但是呢,程序也不能解密了,这个就不太行了,那我们该怎么办呢?

 

很简单,在IDEA中配置一下环境参数即可:

--jasypt.encryptor.password=你的秘钥

微信截图_20240927163808.png

 

六:配置服务器运行参数

在本地开发中,我们已经配置完成,那么打成jar包之后在服务器中运行该怎么办呢?

 

很简单,在执行jar包的命令中添加运行参数即可:

java -Xms256M -Xmx256M -jar / java/app.jar --jasypt.encryptor.password=xxxxx

 

到这里,在springboot项目中集成jasypt加密库对yml中的敏感参数混淆就完成了。

 

七:在代码中使用jasypt

上边呢,我们是不在yml中配置jasypt.encryptor.password值的。

 

但是如果我们配置了password值,就需要在启动类加上@EnableEncryptableProperties这个注解,用于自动解密。

 

 

有好的建议,请在下方输入你的评论。