目录
环境信息
基础信息
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";
}
}
开始配置
pom导入
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
方法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));
}
}
执行结果示例
配置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
开启配置
实际测试中发现也可不配置,使用说明可参考附录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);
}
}
测试
启动微服务
启动参数: -Dpwd=redisPWD@redisPWD 或 -Djasypt.encryptor.password=redisPWD@redisPWD
使用默认配置
密码注入前(properties读取后)已正确解密
写入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);
}
};
}
}
配置SpringBoot 配置文件
无关配置已删除(jasypt配置全部使用默认,password参数通过启动命令传入)
spring:
redis:
host: localhost
port: 6379
password: ENC(GGAVHcW4MUc=)
开启配置
参考方法一(建议配置)
测试
过程略
解密过程
附
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;
/**
* <p>Annotation that enables Jasypt for properties decryption by annotating {@link Configuration} classes.
* Only one occurrence of this annotation is needed.</p>
* <p>
* <p>This works well in conjunction with the {@link org.springframework.context.annotation.PropertySource} annotation.
* For instance:</p>
* <pre>
* {@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);
* }
* }
* </pre>
* <p>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.<p/>
* <p>
* <p>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.</p>
* <p>
* For more information on how to declare encrypted properties, encrypt them, and encryption configuration go to <a href="http://jasypt.org">http://jasypt.org</a>
* </p>
*
* @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 {
}
划重点