• Spring Boot demo系列(九):Jasypt


    2021.2.24 更新

    1 概述

    Jasypt是一个加密库,Github上有一个集成了JasyptSpring Boot库,叫jasypt-spring-boot,本文演示了如何使用该库对配置文件进行加密。

    2 依赖

    首先添加依赖:

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

    Gradle

    implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3")
    

    3 简单加密

    简单加密就是直接把加密口令(注意不是加密密码)以明文形式写在配置文件中,步骤如下:

    • 配置文件配置加密口令
    • 获取密文
    • 替换明文

    3.1 加密口令

    在配置文件加上如下参数:

    jasypt:
      encryptor:
        password: test
    

    其中test就是加密的口令。

    3.2 获取密文

    比如配置文件需要加密的值如下:

    test: value
    

    在测试类对StringEncryptor进行注入并使用其中的encrypt加密通过@Value获取的值:

    @SpringBootTest
    class DemoApplicationTests {
        @Autowired
        private StringEncryptor encryptor;
    
        @Value("${test}")
        private String value;
    
        @Test
        void contextLoads() {
            System.out.println(encryptor.encrypt(value));
        }
    }
    

    点击旁边的绿色小三角形即可运行,输出如下:

    在这里插入图片描述

    这个就是对应的密文。

    3.3 替换明文

    把密文加上前缀ENC(与后缀)替换明文:

    test: ENC(IlEvyvcULhZJrHLDtPun2ut433RvAdpaNJ9IZt9uNUk3hDSKQsdOXLEkWyiK6QR3)
    

    这样就完成了对属性test进行加密。

    3.4 测试

    直接通过@Value获取的值即为明文:

    @SpringBootTest
    class DemoApplicationTests {
    
        @Autowired
        private StringEncryptor encryptor;
    
        @Value("${test}")
        private String value;
    
        @Test
        void contextLoads() {
            System.out.println(encryptor.encrypt(value));
        }
    
        @Test
        void decrypt()
        {
            System.out.println(value);
        }
    }
    

    直接运行其中的decrypt即可输出明文。

    4 自定义加密

    4.1 自定义加密类

    默认采用的加密算法为PBE算法,如果觉得不能符合要求可以自定义加密类。

    在这里插入图片描述

    自定义加密类实现StringEncrypto接口即可,需要在配置文件写上Bean的名称:

    @Component
    public class Encryptor implements StringEncryptor{
    
        @Override
        public String encrypt(String s) {
            return s+"111";
        }
    
        @Override
        public String decrypt(String s) {
            return s.substring(0,s.indexOf("111"));
        }
    }
    

    这里的加密很简单,直接在明文后面加上111,解密的话去掉111。另外在配置文件上写上Bean的名称:

    jasypt:
      encryptor:
    #    password: test
        bean: encryptor
    

    同时可以把口令注释掉,因为此时已经不需要使用口令进行加密了。

    测试:

    @SpringBootTest
    class DemoApplicationTests {
    
        @Autowired
        private StringEncryptor encryptor;
    
        @Value("${test}")
        private String value;
    
        @Test
        void contextLoads() {
            System.out.println(encryptor.encrypt(value));
        }
    
        @Test
        void decrypt()
        {
            System.out.println(encryptor.decrypt(value));
        }
    
    }
    

    4.2 非对称加密

    生成公钥与私钥借助了工具类库Hutool,依赖如下:

    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-crypto</artifactId>
        <version>5.4.3</version>
    </dependency>
    
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.66</version>
    </dependency>
    

    Gradle

    implementation("cn.hutool:hutool-crypto:5.4.3")
    implementation("org.bouncycastle:bcprov-jdk15on:1.66")
    

    生成公钥私钥:

    KeyPair pair = SecureUtil.generateKeyPair("RSA");
    System.out.println(Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()));
    System.out.println(Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded()));
    

    生成后添加到jasypt.encryptor.public-key-stringjasypt.encryptor.private-key-string

    jasypt:
      encryptor:
    #    password: test
    #    bean: encryptor
        public-key-string: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZV5U0+Ck4AEpawUoiHOkG4ZNC6EeEvFZVCcyaIM0MiusGMM6ye9ZT6Ok756/vQsJbsYDGDtIDX82TsmYbZkN7QPuclABSL5SmaDYdJM/MeYKfMwrDb0lWARqF5ql9Rgol7Agq4ef8yQEbSmUDW/LQe+xXtCTer5MoJViUHV56MwIDAQAB
        private-key-string: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJlXlTT4KTgASlrBSiIc6Qbhk0LoR4S8VlUJzJogzQyK6wYwzrJ71lPo6Tvnr+9CwluxgMYO0gNfzZOyZhtmQ3tA+5yUAFIvlKZoNh0kz8x5gp8zCsNvSVYBGoXmqX1GCiXsCCrh5/zJARtKZQNb8tB77Fe0JN6vkyglWJQdXnozAgMBAAECgYA8syFCrwtt+ht00ne8ijIqQagP/6+z2PPZxL/DsUFJ+kGvmSlxGLlOTO/qgTuxG/2g22JsxFgY8tcHZMKrjO8f4TLKPsaFgX1OwNhJO4SoMlfUUAR9HSMv49vx5mOvh2QUrC5+4rIQI1Rm8zbKyAqCjHIKr8hA6bIKEHO2qXK05QJBANhAA+djwrr3orIIBTRp+H6/JChH76XtoQfcQyT+CrEu/4tHVkbO2cEqcdKDScswHyTPu5UaSU2HFW/0Lj8Kg40CQQC1h1YMysd51djCf/Ud7L2sSIduy3DUSLc6XRX1IWAqxO+8gkvknDW7QztNES9YqwYEkLNLAjp1v8Gq+o2JQKS/AkAENCpfQycz70BwaYuAW1cDT7/qMIvOE/J/bp63h2C51QoOsRJSSg8dnC+eQgMbOhJA6vDgkyQ9p5SZGowTmaa5AkEAneQAIZJC3KL3LX20ivm+pFpVijXjhpFU5avPjG4iQjEXQISoVEjWp3G747V91Aa1bkUZ3bUref13Cytw7h/O6wJBAJHNIHKKTAkmslguJU5hll1HqrzyI9lcB5XqcgvdsxijUkZ95FThk6hNQuNV0sO/itUijQsJAtNdDITKmdcPMWg=
    

    然后就可以像加密得到密文并替换明文了。

    5 非明文口令

    对于jasypt.encryptor.password,可以使用非明文口令,这样口令的传递方式有三种:

    • 通过命令行参数传递
    • 通过应用环境变量传递
    • 通过系统环境变量传递

    5.1 通过命令行参数传递

    首先先写上明文口令,得到密文:

    jasypt:
      encryptor:
        password: test
    test: value
    

    在这里插入图片描述

    加上前后缀替换明文后,去掉加密口令:

    #jasypt:
    #  encryptor:
    #    password: test
    
    test: ENC(quCu1b+Z7SPHmgVsmbkeyNZmNe1LJw+SxjmwwLjNaWoH/ce3r6iHGvaMN5eQcu0P)
    

    并在测试类的参数类加上

    --jasypt.encryptor.password=test
    

    在这里插入图片描述

    由于这里是测试类命令行参数添加不了,但是在启动类是可以添加的:

    在这里插入图片描述

    这种方法就跳过演示了。

    对于Gradle,测试的时候需要在build.gradle/build.gradle.kts添加参数:

    tasks.withType<Test> {
        useJUnitPlatform()
        jvmArgs("-Djasypt.encryptor.password=test")
        // 不能是jvmArgs("--jasypt.encryptor.password=test")
    }
    

    5.2 通过应用环境变量传递

    和第一种方式差不多,第一种在Program arguments设置,而这种方法在VM options中设置:

    -Djasypt.encryptor.password=test
    

    在这里插入图片描述

    在这里插入图片描述

    5.3 系统环境变量方式传递

    通过系统环境变量方式传递jasypt.encryptor.password时,需要指定是哪一个环境变量:

    jasypt:
      encryptor:
        password: ${ENCRYPT}
    

    比如这里指定的是ENCRYPT环境变量,设置好环境变量后就可以直接加密解密了。

    6 部署注意事项

    6.1 打包

    因为在配置文件中缺少了jasypt.encryptor.password,因此使用Maven打包时会出错:

    在这里插入图片描述

    Maven打包配置中加上参数即可:

    在这里插入图片描述

    但是使用Gradle打包时不需要添加额外的参数。

    6.2 部署

    现在一般通过JAR直接部署即可,也就是通过

    java -jar demo.jar
    

    部署,这时候根据需要加上对应的参数即可,比如:

    java -jar demo.jar --jasypt.encryptor.password=test
    java -Djasypt.encryptor.password=test -jar demo.jar
    

    如果通过系统变量获取加密口令,请确保对应的环境变量存在。

    另外,如果通过Docker部署,请在ENTRYPOINT加上对应参数,比如:

    ENTRYPOINT ["java","-Djasypt.encryptor.password=test","-jar","demo.jar"]
    ENTRYPOINT ["java","-jar","demo.jar",,"--jasypt.encryptor.password=test",]
    

    通过系统环境变量获取请加上ENV

    ENV ENCRYPT="test"
    

    7 参考源码

    Java版:

    Kotlin版:

  • 相关阅读:
    1282 回文数猜想
    1279 验证角谷猜想
    1205 吃糖果
    1201 18岁生日
    1106 排序
    2024 C语言合法标识符
    196 让气球飞吧
    1001 Sum Problem
    if语句
    三元运算符
  • 原文地址:https://www.cnblogs.com/6b7b5fc3/p/13725721.html
Copyright © 2020-2023  润新知