• [SpringBoot]基于jasypt-spring-boot-starter对配置加解密


    环境信息

    基础信息

    Springboot:2.5.6
    jasypt:jasypt-spring-boot-starter: 3.0.4
    Redis: spring-boot-starter-data-redis:2.5.6

    测试类

    redis 写入: GET http://localhost:8889/redis/set/{key}/{val}
    redis读取: GET http://localhost:8889/redis/get/{key}

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/redis")
    public class RedisController {
        @Autowired
        private RedisTemplate redisTemplate;
        @GetMapping("get/{key}")
        public String get(@PathVariable("key")String key) {
            Object o = redisTemplate.opsForValue().get(key);
            return o == null ?"val is null":o.toString();
        }
        @GetMapping("set/{key}/{val}")
        public String set(@PathVariable("key")String key,@PathVariable("val")String val) {
            redisTemplate.opsForValue().set(key,val);
            return "OK";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    开始配置

    pom导入

    <dependency>
    	<groupId>com.github.ulisesbocchiogroupId>
    	<artifactId>jasypt-spring-boot-starterartifactId>
    	<version>3.0.4version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法1(仅配置)

    本方法仅演示最基础的使用,更多的方式自行研究

    密码生成

    测试加密/解密,至于为什么要这么写,可以参考 附录1

    import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
    import org.jasypt.salt.ZeroSaltGenerator;
    
    public class EncryptorUtils {
        private static final String PASSWORD_INFO = "redisPWD@redisPWD";
        public static void main(String[] args) {
            StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
            standardPBEStringEncryptor.setPassword(PASSWORD_INFO);
            standardPBEStringEncryptor.setSaltGenerator(new ZeroSaltGenerator());
            //解密后的文本
            String redisPwd = standardPBEStringEncryptor.encrypt("redis");
            System.out.println("redis=" + redisPwd);
            System.out.println("redis=" + standardPBEStringEncryptor.decrypt(redisPwd));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    执行结果示例

    在这里插入图片描述

    配置SpringBoot 配置文件

    无关配置已删除

    spring:
      redis:
        host: localhost
        port: 6379
        password: ENC(GGAVHcW4MUc=)
    jasypt:
      encryptor:
        algorithm: PBEWithMD5AndDES
        #password 也可以写死成redisPWD@redisPWD(加密解密需要对应)
        #也可以写成如下方式,通过启动参数传入
        password: ${pwd}
        salt-generator-classname: org.jasypt.salt.ZeroSaltGenerator
        iv-generator-classname: org.jasypt.iv.NoIvGenerator
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    开启配置

    实际测试中发现也可不配置,使用说明可参考附录2

    import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @Slf4j
    @SpringBootApplication
    // 此注解开启配置生效,
    @EnableEncryptableProperties
    public class DemoApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    测试

    启动微服务

    启动参数: -Dpwd=redisPWD@redisPWD 或 -Djasypt.encryptor.password=redisPWD@redisPWD
    使用默认配置

    在这里插入图片描述

    密码注入前(properties读取后)已正确解密
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/c1e4d8736ba4421bb59d2f246f356d6f.png

    写入redis

    在这里插入图片描述

    读取redis

    在这里插入图片描述

    方法2(自定义)

    实现自己的加解密配置

    使用默认的配置BeanName,省区修改配置文件

    import com.ulisesbocchio.jasyptspringboot.properties.JasyptEncryptorConfigurationProperties;
    import org.jasypt.encryption.StringEncryptor;
    import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
    import org.jasypt.salt.ZeroSaltGenerator;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableConfigurationProperties(JasyptEncryptorConfigurationProperties.class)
    public class MyEncryptorConfig {
        /**
         * 默认找jasyptStringEncryptor这个bean,这里直接取这个名字进行注册,省去额外配置
         * @param properties
         * @return
         */
       @Bean
        StringEncryptor jasyptStringEncryptor(JasyptEncryptorConfigurationProperties properties){
            return new StringEncryptor() {
                // 加密
                @Override
                public String encrypt(String message) {
                    // todo加密实现
                    return message;
                }
    
                // 解密
                @Override
                public String decrypt(String encryptedMessage) {
                    StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
                    standardPBEStringEncryptor.setPassword(properties.getPassword());
                    standardPBEStringEncryptor.setSaltGenerator(new ZeroSaltGenerator());
                    return standardPBEStringEncryptor.decrypt(encryptedMessage);
                }
            };
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    配置SpringBoot 配置文件

    无关配置已删除(jasypt配置全部使用默认,password参数通过启动命令传入)

    spring:
      redis:
        host: localhost
        port: 6379
        password: ENC(GGAVHcW4MUc=)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    开启配置

    参考方法一(建议配置)

    测试

    过程略

    解密过程

    在这里插入图片描述
    ####

    1.如何确定默认的加密/解密使用的是哪个工具类

    知道这个问题即可解答密码生成为什么要那样写?
    通过查看加配置类入口,发现StringEncryptor的默认实现(beanName)为lazyJasyptStringEncryptor(类型:DefaultLazyEncryptor)

    在这里插入图片描述

    当找不到jasypt.encryptor.bean(默认jasyptStringEncryptor)对应的值时,默认初始化String Encryptor

    在这里插入图片描述
    在这里插入图片描述

    当设置了密码属性后,默认采用PBE算法

    在这里插入图片描述

    PBE算法默认使用StandardPBEStringEncryptor实现
    在这里插入图片描述
    实际加密/解密由StandardPBEByteEncryptor完成

    在这里插入图片描述
    也即对应密码加解密测试中为什么要那么写了

    2.EnableEncryptableProperties

    package com.ulisesbocchio.jasyptspringboot.annotation;
    
    import com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesConfiguration;
    import com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesBeanFactoryPostProcessor;
    import com.ulisesbocchio.jasyptspringboot.wrapper.EncryptablePropertySourceWrapper;
    import org.jasypt.encryption.StringEncryptor;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.core.env.Environment;
    import org.springframework.core.env.PropertySource;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 

    Annotation that enables Jasypt for properties decryption by annotating {@link Configuration} classes. * Only one occurrence of this annotation is needed.

    *

    *

    This works well in conjunction with the {@link org.springframework.context.annotation.PropertySource} annotation. * For instance:

    *
     *  {@literal @SpringBootApplication}
     *  {@literal @EnableEncryptableProperties}
     *  {@literal @PropertySource(name="EncryptedProperties", "classpath:app.properties")}
     *   public class MySpringBootApp {
     *      public static void main(String[] args) {
     *          SpringApplication.run(MySpringBootApp.class, args);
     *      }
     *   }
     * 
    *

    The above code will then enable encryptable properties within all {@link PropertySource}s defined in the environment, * not only the ones defined with the {@link org.springframework.context.annotation.PropertySource} annotation, but also * all system properties, command line properties, and those auto-magically picked up from application.properties and application.yml * if they exist.

    *

    *

    This Configuration class basically registers a {@link BeanFactoryPostProcessor} that wraps all {@link PropertySource} defined in the {@link Environment} * with {@link EncryptablePropertySourceWrapper} and defines a default {@link StringEncryptor} for decrypting properties * that can be configured through the same properties it wraps.

    *

    * For more information on how to declare encrypted properties, encrypt them, and encryption configuration go to http://jasypt.org *

    * * @author Ulises Bocchio * @see EnableEncryptablePropertiesConfiguration * @see EnableEncryptablePropertiesBeanFactoryPostProcessor * @see EncryptablePropertySourceWrapper * @see org.springframework.context.annotation.PropertySource */
    @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Import(EnableEncryptablePropertiesConfiguration.class) public @interface EnableEncryptableProperties { }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    划重点
    在这里插入图片描述

  • 相关阅读:
    包装类详解(装箱(包)、拆箱(包)、Integer类型缓存)
    Pandas
    电脑如何设置开机密码?详细教程来了
    The Missing Semester
    python绘图小dome
    【论文阅读】时序动作检测系列论文精读(2017年 上)
    【JAVA】面向对象的编程语言(继承篇)
    Promise, async, await 学习
    部署APK时遇到 Failed to read key xxxkey from store “xxx.jks“ Cannot recover key修改一法
    Spring的bean装配和bean的自动装配
  • 原文地址:https://blog.csdn.net/master336/article/details/126013530