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···皆可在配置文件配置,有需要的自行查阅官网,这里不做分析。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐