jasypt加密器使用

young 1,367 2022-06-27

github

官网

最近项目中的war包都改为了jar包,原本是采用tomcat用配置jndi,通过tomcat对数据源进行解密

现在采用jasypt进行数据源加解密操作

引入依赖

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
  	<version>${jasypt.version}</version>
</dependency>

由官网可以看到,jasypt分为了5类

  • General digesting 一般摘要

  • Password encryption 密码摘要

  • Text encryption 文本加密

  • Number encryption 数字加密

  • Binary encryption 二进制加密

摘要不可逆,所以无法适用于数据源加密的场景,所以适用Text encryption 文本加密处理。

对比EnableEncryptablePropertiesConfiguration类的注释,或者JasyptEncryptorConfigurationProperties类,可以看到默认配置的差异

jasypt2.x

Key Required Default Value 描述
jasypt.encryptor.password True -
jasypt.encryptor.algorithm False PBEWithMD5AndDES 加密算法
jasypt.encryptor.keyObtentionIterations False 1000 迭代次数
jasypt.encryptor.poolSize False 1 池大小
jasypt.encryptor.providerName False SunJCE
jasypt.encryptor.saltGeneratorClassname False org.jasypt.salt.RandomSaltGenerator 生成盐的类
jasypt.encryptor.ivGeneratorClassname False org.jasypt.iv.NoIvGenerator 向量生成器类
jasypt.encryptor.stringOutputType False base64 输出类型

jasypt3.x

Key Required Default Value
jasypt.encryptor.password True -
jasypt.encryptor.algorithm False PBEWITHHMACSHA512ANDAES_256 加密算法
jasypt.encryptor.keyObtentionIterations False 1000 迭代次数
jasypt.encryptor.poolSize False 1 池大小
jasypt.encryptor.providerName False SunJCE
jasypt.encryptor.saltGeneratorClassname False org.jasypt.salt.RandomSaltGenerator 生成盐的类
jasypt.encryptor.ivGeneratorClassname False org.jasypt.iv.RandomIvGenerator 向量生成器类
jasypt.encryptor.stringOutputType False base64 输出类型
默认加密算法:PBEWITHHMACSHA512ANDAES_256
默认的迭代次数: 1000
默认池大小: 1
默认生成盐的类:org.jasypt.salt.RandomSaltGenerator
默认IV生成器类:org.jasypt.iv.RandomIvGenerator
默认输出类型:base64

2.x版本和3.x版本相比,默认的加密算法,和默认的IV生成器类都有了变化,所以生成加密字符串和进行解密操作时,最好指定加密算法和IV生成器等配置,否则就会出现升级之后,原来的密码无法解密的问题。

可以使用在配置文件中指定jasypt.encryptor.algorithmjasypt.encryptor.ivGeneratorClassname,也可以在命令行参数上指定-Djasypt.encryptor.algorithm-Djasypt.encryptor.ivGeneratorClassname

生成加密字符串

可以使用JasyptPBEStringEncryptionCLI.main()进行字符串加密,在main方法中传入一个String数组。

可以参考org.jasypt.intf.cli.ArgumentNaming生成String数组。

private String password = "xTcGaZUhY4Mg";

    @Test
    public void encrypt() {
        String[] arg = {"input=test_str", "password=" + password,"algorithm=PBEWithMD5AndDES","ivGeneratorClassName=org.jasypt.iv.NoIvGenerator"};
        JasyptPBEStringEncryptionCLI.main(arg);
    }
----ENVIRONMENT-----------------

Runtime: Azul Systems, Inc. OpenJDK 64-Bit Server VM 25.322-b06 



----ARGUMENTS-------------------

ivGeneratorClassName: org.jasypt.iv.NoIvGenerator
algorithm: PBEWithMD5AndDES
input: test_str
password: xTcGaZUhY4Mg



----OUTPUT----------------------

XNxNEWosJ8Topf22PlETWe5FvGWVf/z3

解密字符串

可以使用JasyptPBEStringDecryptionCLI.main()解密字符串,用法与加密一致,input为被加密的字符串。

项目配置文件中配置解密

比如上面生成的XNxNEWosJ8Topf22PlETWe5FvGWVf/z3就是我们敏感信息被加密后的数据,那么在配置中,需要使用ENC()将需要解密的字符串进行包裹,如ENC(XNxNEWosJ8Topf22PlETWe5FvGWVf/z3)

可以通过jasypt.encryptor.property.prefixjasypt.encryptor.property.suffix进行更改

同时需要配置密码,用于解密,使用配置jasypt.encryptor.password进行配置。

例如:

jasypt:
  encryptor:
    password: xTcGaZUhY4Mg
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
spring:
	datasource:
		password: ENC(XNxNEWosJ8Topf22PlETWe5FvGWVf/z3)
    username: test
    ......

这种常用的方式为对称加密。

jasypt也支持非对称加密的方式。

查看com.ulisesbocchio.jasyptspringboot.configuration.StringEncryptorBuilder#build方法,可以看到jasypt创建默认的字符串加密器时,会根据配置情况,创建对称加密器或非对称加密器。

public StringEncryptor build() {
    if (isPBEConfig()) {
        return createPBEDefault();
    } else if (isAsymmetricConfig()) {
        return createAsymmetricDefault();
    } else {
        throw new IllegalStateException("either '" + propertyPrefix + ".password' or one of ['" + propertyPrefix + ".private-key-string', '" + propertyPrefix + ".private-key-location'] must be provided for Password-based or Asymmetric encryption");
    }
}
private boolean isPBEConfig() {
    return configProps.getPassword() != null;
}

private boolean isAsymmetricConfig() {
    return configProps.getPrivateKeyString() != null || configProps.getPrivateKeyLocation() != null || configProps.getPublicKeyString() != null || configProps.getPublicKeyLocation() != null;
}

可以根据自身的需求进行配置。

其余使用API进行加解密的场景,可以参考官方文档给出的示例。