SpringBoot配置文件加密
SpringBoot配置文件加密
当我们在发布项目部署的时候,是否会发现配置文件被暴露在环境中,且配置文件里面的密码为明文,这样非常不安全。
例如:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
username: root
#明文 不安全
password: 123456
redis:
database: 0
#明文 不安全
password: 123456
port: 6379
这是我们需要一个加密组件jasypt-spring-boot
一、引入组件依赖
<!--配置文件加密-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
二、加入加密密钥(盐)
我们在application.yaml中加入以下配置
jasypt:
encryptor:
password: louchen
可以理解为jasypt
会使用这个自定义加密密钥,对配置文件里的重要项进行加密。
三、加密测试
使主配置类实现CommandLineRunner
接口,在启动程序时输出指定内容
@SpringBootApplication
public class VrhApplication implements CommandLineRunner {
@Autowired
private ApplicationContext appCtx
@Autowired
private StringEncryptor stringEncryptor;
public static void main(String[] args) {
SpringApplication.run(VrhApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
//读取配置文件
Environment environment = appCtx.getBean(Environment.class);
// 首先获取配置文件里的原始明文信息
String mysqlOriginPswd = environment.getProperty("spring.datasource.password");
String redisOriginPswd = environment.getProperty("spring.redis.password");
String mysqlencrypt = encrypt(mysqlOriginPswd);
System.out.println("加密:"+mysqlOriginPswd+">>>>>密文:"+ mysqlencrypt);
System.out.println("解密:>>>>>明文:"+decrypt(mysqlencrypt));
System.out.println("----------------");
String redisencrypt = encrypt(redisOriginPswd);
System.out.println("加密:"+mysqlOriginPswd+">>>>>密文:"+ redisencrypt);
System.out.println("解密:>>>>>明文:"+decrypt(redisencrypt));
}
/**
* 加密
* @param orginPws 明文
* @return
*/
private String encrypt(String orginPws){
return stringEncryptor.encrypt(orginPws);
}
/**
*解密
* @param depryptPwd 密文
* @return
*/
private String decrypt(String depryptPwd){
return stringEncryptor.decrypt(depryptPwd);
}
}
四、修改配置文件替换明文
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
username: root
#替换的密文
password: ENC(HRdQoZQEkagFOmHEFP3+FAPHasQJoxHmgezz559eMnBhGj2W1nj)
redis:
database: 0
#替换的密文
password: ENC(YJvMXx9L4h3dr3gPFr+lm1wA1WGTordEGSDhymm8YtnN43yReAp5udGy662)
port: 6379
这里我们可以看出。在代码中使用时,jasypt-spring-boot
组件会自动将ENC()
语法包裹的配置项加密字段自动解密,数据得以还原。
五、加密密钥为什么在ENC()中,可以更改吗?
自定义加密前缀
jasypt:
encryptor:
property:
prefix: lc(
suffix: )
再次修改application.yaml
文件
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
username: root
#替换的密文
password: lc(HRdQoZQEkagFOmHEFP3+FAPHasQJoxHmgezz559eMnBhGj2W1nj)
redis:
database: 0
#替换的密文
password: lc(YJvMXx9L4h3dr3gPFr+lm1wA1WGTordEGSDhymm8YtnN43yReAp5udGy662)
port: 6379
六、担心jasypt.encryptor.password设置的盐被泄露?
我们的加密密钥放在配置application.yaml中难免有些不安全,这时我们可以使用自定义加密器
使用自定义加密器
我们自自定义一个加密器配置类即可
@Configuration
public class ConfigEncryptBean {
@Bean
public StringEncryptor lcEncryptBean() {
PooledPBEStringEncryptor encryptor=new PooledPBEStringEncryptor();
SimpleStringPBEConfig config=new SimpleStringPBEConfig();
// 设置盐
config.setPassword("louchen");
// 设置加密算法
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
// 迭代次数
config.setKeyObtentionIterations("1000");
// 池的大小
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
注意:上面bean的名字默认为方法名。我们可以使用@Bean注解更改bean的名称·
更改application.yaml
# 加密配置
jasypt:
encryptor:
property:
prefix: lc(
suffix: )
bean: lcEncryptBean
这是我们的密钥盐就在bean中,比较安全的防止别人获取盐
七、其他密钥设置方式
方式一:直接作为程序启动时的命令行参数来带入
java -jar yourproject.jar --jasypt.encryptor.password=louchen
方式二:直接作为程序启动时的应用环境变量来带入
java -Djasypt.encryptor.password=louchen -jar yourproject.jar
方式三:甚至可以作为系统环境变量的方式来带入
比方说,我们提前设置好系统环境变量JASYPT_ENCRYPTOR_PASSWORD = louchen
,则直接在Spring Boot的项目配置文件中做如下配置即可:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
这时候也会安全得多。