jasypt对配置文件加密

2024-04-15 17:19:52 浏览数 (1)

1、需求

1)密码配置不能显示为明文,有安全隐患;

2)要支持程序启动时动态加解密密文密码,且密钥也不能直接写在配置文件中;

3)相同的密码对应的密文不能一致,需要加盐处理;

2、解决办法

使用 jasypt 第三方库解决此问题,以数据库和redis密码为例:

测试的配置:

代码语言:bash复制
spring.datasource.url: jdbc:mysql://172.20.1.1:3307/3306?useUnicode=true&characterEncoding=utf8&useSSL=true&verifyServerCertificate=false&trustServerCertificate=true&allowMultiQueries=true
spring.datasource.username: root
spring.datasource.password: root@123
spring.redis.password: root@123

上线的配置:

代码语言:bash复制
spring.datasource.url: jdbc:mysql://172.20.1.1:3306/portal?useUnicode=true&characterEncoding=utf8&useSSL=true&verifyServerCertificate=false&trustServerCertificate=true&allowMultiQueries=true
spring.datasource.username: root
spring.datasource.password: ENC(jiLHnOdWJuHAOC6DsR2XmyJe7LuGWD l/3izm7bYjPdv5W6Ge8IqDNeylEBuS11e)
spring.redis.password: ENC(m xVkutzcODyHsXIeHtYgk6awNdFv69DiGHJXqbsfsjRsXOiHOu3WKkOq2OIJrYa)

这里可以看到,redis和mariadb相同的密码,其密文是不一致的。而且配置文件中不需要任何jasypt的配置。程序可以正常启动并解密。

操作说明:

这里只需要默认注册一个StringEncryptor的Bean即可,把密码写死在代码中。

代码语言:java复制
@Configuration
public class DefaultJasyptConfig {

    public static final String SALT_PASSWORD = "your_uuid";

    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        // 这里配置了全局的配置密码,jasypt会自动加盐,不用配置盐值。
        config.setPassword(SALT_PASSWORD);
        config.setAlgorithm("PBEWithHMACSHA512AndAES_256");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }
}

这里需要注意的是:3.0.0以后的jasypt版本,加密算法需要配置成PBEWithHMACSHA512AndAES_256,其默认的加解密类是AES256TextEncryptor。IvGeneratorClassName可以设置成RandomIvGenerator。

1.x和2.x.x的jasypt版本默认的加密算法是PBEWithMD5AndDES,其默认加密类是:BasicTextEncryptor。IvGeneratorClassName需要设置成NoIvGenerator。

我这里使用的是3.0.4版本,spring-boot依赖为2.5.4。

代码语言:java复制
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.4</version>
</dependency>

3、生成密文

这里还有一个问题就是密码的密文怎么生成,可以使用测试类,也可以提供一个rest接口。方法比较简单。

代码语言:java复制
@SuppressWarnings("RegexpSinglelineJava")
public final class JasyptUtil {

    private JasyptUtil() {
    }

    public static String encrypt(String configPassword, String targetString) {
        AES256TextEncryptor encryptor = new AES256TextEncryptor();
        encryptor.setPassword(configPassword);
        return encryptor.encrypt(targetString);
    }

    public static String decrypt(String configPassword, String targetString) {
        AES256TextEncryptor encryptor = new AES256TextEncryptor();
        encryptor.setPassword(configPassword);
        return encryptor.decrypt(targetString);
    }

    /**
     * 配置文件的密码生成和测试.
     * @param args unused
     */
    public static void main(String[] args) {
        String configPassword = "a57fc561-e051-4e5a-abea-1c4c530cfe44";
        String realPassword = "fitview.1";
        // 进行加密操作
        String encryptPassword = encrypt(configPassword, realPassword);
        // 进行解密操作
        String decryptPassword = decrypt(configPassword, encryptPassword);
        // 输出明文和密文
        System.out.println("encryptPassword="   encryptPassword);
        System.out.println("decryptPassword="   decryptPassword);
    }
}

上面是3.0.x的写法,2.0.0以下的写法:把AES256TextEncryptor换成BasicTextEncryptor即可。这个取决于你在config类里面设置的加密算法。

(PBEWithHMACSHA512AndAES_256 对应 AES256TextEncryptor )

(PBEWithMD5AndDES 对应 BasicTextEncryptor)

当然,你也可以自己实现TextEncryptor定义你自己的加密算法。

0 人点赞