1.版本说明及引用
因为考虑到我的项目springboot-boot-starter是2.2.6RELEASE版本,所以关于jasypt使用的是jasypt-spring-boot-starter 3.0.3版本。
mvn:
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
gradle:
// https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter
compile group: 'com.github.ulisesbocchio', name: 'jasypt-spring-boot-starter', version: '3.0.3'
其实使用jasypt-spring-boot包同版本也一样,但是要比-starter版本在主方法头上多加一个注解@EnableEncryptableProperties
目前在mvn库能查到最新的就是3.0.3版本,对应的是springboot-boot-starter 2.2.1RELEASE,在这也以3.0.3来探讨。
目前我用3.0.3发现有时会出现绑定String的错:
Failed to bind properties under 'jasypt.encryptor.password' to java.lang.String:
Reason: Failed to bind properties under 'jasypt.encryptor.password' to java.lang.String
需要自己重新对敏感信息做加密,查看是否有空格的地方,实在不行就下调使用2.1.2版本,因为有的人用3.0.3一直报这个错,我的目前处理没问题。
如果想用其他版本的可以自行尝试查询,这里不做多余讲解,版本不匹配会出现ParameterMapping错误。
2.Java代码使用
在配置yml中添加如下加盐处理,properties自行转化
jasypt:
encryptor:
password: 71144850f4fb4cc55fc0ee6935badddf
这个password只是为了对你的要加密解密的字符串加盐,非真正要加密的串。
然后就可以进行java测试了
controller测试:
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class TestController extends CommonController {
@Autowired
private StringEncryptor encryptor;
/**
* 测试jasypt加密解密
*/
@GetMapping("/jasypt")
public void testJasypt() {
String password = "123456";
String encryptPwd = encryptor.encrypt(password);
System.out.println("encryption: " + encryptPwd);
System.out.println("decryption: " + encryptor.decrypt(encryptPwd));
}
}
结果:
Test Unit4测试:
import com.ericsson.bit.sqa.BITOauth2Application;
import org.jasypt.encryption.StringEncryptor;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author eujiunc
* @date 2021-01-22 13:43:58
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = BITOauth2Application.class)
public class JasyptUtilTest {
@Autowired
private StringEncryptor encryptor;
@Test
public void jasypt(){
String name = encryptor.encrypt("hello");
System.out.println("en: " + name);
System.out.println("de: " + encryptor.decrypt(name));
}
}
结果:
如果没在配置中配置加盐会出现如下错误
[2021-01-22 13:55:33][ERROR][ANONYMOUS] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: either 'jasypt.encryptor.password' or one of ['jasypt.encryptor.private-key-string', 'jasypt.encryptor.private-key-location'] must be provided for Password-based or Asymmetric encryption] with root cause
java.lang.IllegalStateException: either 'jasypt.encryptor.password' or one of ['jasypt.encryptor.private-key-string', 'jasypt.encryptor.private-key-location'] must be provided for Password-based or Asymmetric encryption
正常都能加密解密后即可对配置文件中的敏感信息进行处理
对要加密的敏感信息进行jasypt加密处理后,需要在配置文件用ENC(加密串)进行配置文件加密。
这样即可正常启动程序而达到配置文件加密的目的。
正常如果用java ide进行对敏感加密解密测试即可到此为止,但如果用命令行对jasypt包进行操作加密解密可能会出现很多坑,遇到的同学请往下看下去。
3.使用JVM操作jasypt加密解密
首先确认项目是使用的maven还是gradle管理jar包,然后再通过仓库地址去找
如果是使用的maven没有覆盖仓库,默认在C:\Users\用户名\.m2\repository\org\jasypt\jasypt\1.9.3下
如果是使用的gradle没有覆盖仓库,默认在C:\Users\EUJIUNC\.gradle\caches\modules-2\files-2.1\org.jasypt\jasypt\1.9.3\下
注意:下载的是jasypt-spring-boot-starter包但实际找的是org.jasypt:jasypt:1.9.3目录
gradle要注意找的路径在1.9.3下还有三个随机码组成的文件夹,要找的是jasypt-1.9.3.jar,其他两个包分别是jasypt-1.9.3-sources.jar和jasypt-1.9.3.pom
然后在找到的jar目录下cmd命令输入(shift+右键找到powershell window或者在地址栏输入cmd)。
然后就可以使用命令进行jasypt加密解密了。
加密:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=root password=71144850f4fb4cc55fc0ee6935badddf algorithm=PBEWithMD5AndDES
解密:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input=b/Npk/qiyR8Dpi9T/M0oCQ== password=71144850f4fb4cc55fc0ee6935badddf algorithm=PBEWithMD5AndDES
jasypt-1.9.3.jar改成你真正的名称, input:要加密的敏感信息, password:要加密的盐,algorithm:加密方式
按理来说这样就算成功了,但是上面的命令生成的加密串根本就不能通过第二部的java代码解密!细心地人也应该通过加密后的串长度发现加密方式肯定不同,
借鉴了很多文章都是上面照搬的命令,实际都是坑!
在java配置后配置好加盐并进行加密解密测试会发现这样一段话:
在没有配置jasypt.encryptor.algorithm情况下默认使用的加密方式其实是PBEWITHHMACSHA512ANDAES_256
通过源码initialize初始化方法也可以发现当找不到this.provider和this.providerName时默认this.key即加密方式是PBEWITHHMACSHA512ANDAES_256
如果想要命令行使用PBEWITHHMACSHA512ANDAES_256方式加密解密,单纯修改algorithm是行不通的。
需要在后面再加入ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator参数,这是官网给出的解决方案。飞机票
这样即可解决cmd命令行的结果。如果想要在java代码中使用PBEWithMD5AndDES加密解密,需要在配置文件中添加jasypt的algorithm配置。
jasypt:
encryptor:
password: 71144850f4fb4cc55fc0ee6935badddf
algorithm: PBEWithMD5AndDES
至此问题彻底解决,也对jasypt加密解密有了一定了解,其他jasypt的配置如pool-size、provider-name···皆可在配置文件配置,有需要的自行查阅官网,这里不做分析。