最近项目中的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.algorithm
和jasypt.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.prefix
和jasypt.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进行加解密的场景,可以参考官方文档给出的示例。