Jasypt 加密配置文件
典型的配置文件
下面是一份 Spring Boot 项目的application.yml
配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://111.xx.xx.xxx:3306/order?useUnicode=true&characterEncoding=utf-8
redis:
host: 127.0.0.1
port: 6379
password: 123456 # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
database: 0 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。
乍一看这份配置文件没什么问题,因为在平常项目中我们都是这么使用的,但是我们仔细想一下会发现 我们的数据库密码 和 redis密码 是不是都是明文保存,没有做任何加密处理,如果一不小心泄露了出去,后果就不堪设想
如何配置加密项
-
通过
jasypt-spring-boot
这个开箱即用的加密组件来引入Jasypt
这个强大的加密库<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency>
-
配置SpringBoot的yml配置文件 配置 加密密钥
jasypt: encryptor: #自定义加密密钥 password: labors
可以认为
jasypt
会使用这个自定义加密密钥,对配置文件里的重要项进行加密。 -
编写加密测试类
/** * @author yicui * @date 2020-09-08 11:07 下午 */ @SpringBootTest public class Jasypt { @Value("${spring.datasource.password}") private String mysqlPwd; @Value("${spring.redis.password}") private String redisPwd; @Autowired private StringEncryptor codeSheepEncryptorBean; @Test public void encryptPassword() { // 加密 String mysqlEncryptedPwd = encrypt(mysqlPwd); String redisEncryptedPwd = encrypt(redisPwd); System.out.println("mysql加密后的密码:" + mysqlEncryptedPwd); System.out.println("redis加密后的密码:" + redisEncryptedPwd); } @Test public void decryptPassword() { // 解密 System.out.println("mysql解密后的密码:" + mysqlPwd); System.out.println("redis解密后的密码:" + redisPwd); } /** * 加密 * * @param originPassword * @return */ private String encrypt(String originPassword) { return codeSheepEncryptorBean.encrypt(originPassword); } /** * 解密 * * @param encryptedPassword * @return */ private String decrypt(String encryptedPassword) { return codeSheepEncryptorBean.decrypt(encryptedPassword); } }
运行测试类,控制台打印
mysql加密后的密码:n0hBSrWyA138pJoGQRiA0cFbxLkK5l34spRzODJRvOXJMvrwlUFllcO7RqE0IjWn redis加密后的密码:LRUMkFYRIiHADjwP7BGmxKRSbiffyA6Oqas4sJLq6s7tZfUpXHjI2g7vcJD7sVwk
-
修改配置文件,替换加密项
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ENC(n0hBSrWyA138pJoGQRiA0cFbxLkK5l34spRzODJRvOXJMvrwlUFllcO7RqE0IjWn) url: jdbc:mysql://111.xx.xxx.xxx:3306/user?useUnicode=true&characterEncoding=utf-8 redis: host: 127.0.0.1 port: 6379 # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码! password: ENC(LRUMkFYRIiHADjwP7BGmxKRSbiffyA6Oqas4sJLq6s7tZfUpXHjI2g7vcJD7sVwk) database: 0 # Redis 数据库号,默认为 0 。 timeout: 0 # Redis 连接超时时间,单位:毫秒。 # 对应 RedisProperties.Jedis 内部类 jedis: pool: max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。 max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。 min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。 max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制
在配置文件中使用时,我们需要用
ENC()
语法包裹加密字段,代码运行时jasypt-spring-boot
组件会自动将自动解密,数据得以还原。
解密配置加密项
@SpringBootTest
public class Jasypt {
@Value("${spring.datasource.password}")
private String mysqlPwd;
@Value("${spring.redis.password}")
private String redisPwd;
@Autowired
private StringEncryptor codeSheepEncryptorBean;
@Test
public void decryptPassword() {
// Jasypt会自动将加密后的配置项进行解密
System.out.println("mysql解密后的密码:" + mysqlPwd);
System.out.println("redis解密后的密码:" + redisPwd);
}
/**
* 加密
*
* @param originPassword
* @return
*/
private String encrypt(String originPassword) {
return codeSheepEncryptorBean.encrypt(originPassword);
}
/**
* 解密
*
* @param encryptedPassword
* @return
*/
private String decrypt(String encryptedPassword) {
return codeSheepEncryptorBean.decrypt(encryptedPassword);
}
}
运行测试类,控制台打印
mysql解密后的密码:123123
redis解密后的密码:123456
自定义加密后缀
如果不想使用 jasypt
默认提供的ENC
来标记加密字段,完全可以换成自定义的前后缀标记,比如我想换成labors()
来标记加密字段
jasypt:
encryptor:
#自定义加密前后缀
property:
prefix: yicui(
suffix: )
这样加密字段就可以放到 labors()
中了
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: labors(n0hBSrWyA138pJoGQRiA0cFbxLkK5l34spRzODJRvOXJMvrwlUFllcO7RqE0IjWn)
url: jdbc:mysql://111.xx.xxx.xxx:3306/user?useUnicode=true&characterEncoding=utf-8
redis:
host: 127.0.0.1
port: 6379
# Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
password: labors(LRUMkFYRIiHADjwP7BGmxKRSbiffyA6Oqas4sJLq6s7tZfUpXHjI2g7vcJD7sVwk)
database: 0 # Redis 数据库号,默认为 0 。
timeout: 0 # Redis 连接超时时间,单位:毫秒。
# 对应 RedisProperties.Jedis 内部类
jedis:
pool:
max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制
加密更加安全
让加密更加安全,可以选择将加密的密钥不写在配置文件
-
直接作为程序启动时的命令行参数来带入
java -jar project.jar --jasypt.encryptor.password=labors
-
直接作为程序启动时的应用环境变量来带入
java -Djasypt.encryptor.password=labors -jar project.jar
-
可以作为系统环境变量的方式来带入
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
JASYPT_ENCRYPTOR_PASSWORD 为 配置的系统环境变量