大家好,我是神韵,是一个技术&生活博主。出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己。二是希望我的文章可以帮到大家。欢迎来点赞打卡,你们的行动将是我无限的动力。
本篇主题是:SpringBoot 之 Jasypt 实现yml配置文件加密
目录
一、Jasypt3.0及以上版本(注意看版本)
二、Jasypt3.0及以下版本
在我们的项目中各种application-x.yml 配置文件经常会存储一些password的值,如果是明文存储其实是一种安全隐患,很多公司项目交付时是不能过的,我们可以使用SpringBoot的Jasypt 的方式进行加密。官网教学可以参考--https://github.com/ulisesbocchio/jasypt-spring-boot
下面让我们开始,案例,加密数据库用户和密码
1、引入Jasypt依赖 3.0.4,当前日期最新版本
com.github.ulisesbocchio
jasypt-spring-boot-starter
3.0.4
2、假设yml中数据库配置如下,需要加密的是shenyun/shenyun20220907
spring:
datasource:
# 二、非嵌入式数据库配置--MySQL
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useSSL=true
username: shenyun
password: shenyun20220907
3、此时我们需要对它用Jasypt进行加密,重要,还有个秘钥-盐后面再提,假设盐值是"salt20220907",加密代码如下
public static void main(String[] args) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
// 加密方式
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
// 盐值
config.setPassword("salt20220907");
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);
// 加密明文
String encryptValue1 = encryptor.encrypt("shenyun");
String encryptValue2 = encryptor.encrypt("shenyun20220907");
// 解密密文
// String decryptValue = encryptor.decrypt("MaF3AwiV/aXCCDMEx+nOgAtXreq62JMgRM+2M9NIpUe0vko3fahZ+IxnvocfaGnJ");
System.out.println(encryptValue1);
System.out.println(encryptValue2);
// System.out.println(decryptValue);
}
运行后此时我们得到了
shenyun的密文为hEc7NPysxK/gIxN1r6iogy/sadZhFkBLLm+gr55CQKC0nBgCSJXEyU9PmsGi1Li3
shenyun20220907的密文为MaF3AwiV/aXCCDMEx+nOgAtXreq62JMgRM+2M9NIpUe0vko3fahZ+IxnvocfaGnJ
4、修改yml文件为,用ENC(...),Jasypt就会识别
spring:
datasource:
# 二、非嵌入式数据库配置--MySQL
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useSSL=true&serverTimezone=GMT%2B8
username: ENC(hEc7NPysxK/gIxN1r6iogy/sadZhFkBLLm+gr55CQKC0nBgCSJXEyU9PmsGi1Li3)
password: ENC(MaF3AwiV/aXCCDMEx+nOgAtXreq62JMgRM+2M9NIpUe0vko3fahZ+IxnvocfaGnJ)
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
5、加上盐解密,默认是ENC(..)它就会解密,也可以在容器中用${value}取得这个密文。这个盐可以在启动JVM时带入,或者保存在云部署-credential上(盐值应该放在系统属性、命令行或是环境变量来使用),此时yml配置为
spring:
datasource:
# 二、非嵌入式数据库配置--MySQL
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useSSL=true&serverTimezone=GMT%2B8
username: ENC(hEc7NPysxK/gIxN1r6iogy/sadZhFkBLLm+gr55CQKC0nBgCSJXEyU9PmsGi1Li3)
password: ENC(MaF3AwiV/aXCCDMEx+nOgAtXreq62JMgRM+2M9NIpUe0vko3fahZ+IxnvocfaGnJ)
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
jasypt:
encryptor:
password: salt20220907
# 通过jvm参数设置,直接-Djasypt.encryptor.password=salt20220907
# 默认解密识别是是ENC(..),如果需要定制不同,可以进行下面配置,如下ENC@[..]
# property:
# prefix: "ENC@["
# suffix: "]"
6、启动Java程序,发现正常连接数据库则解密成功。
7、因为盐放在了yml上面,也是不安全的,我们可以通过启动参数去配置它,或者配置到云中的credentitl上。下面我将yml的jasypt删掉,即
spring:
datasource:
# 二、非嵌入式数据库配置--MySQL
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useSSL=true&serverTimezone=GMT%2B8
username: ENC(hEc7NPysxK/gIxN1r6iogy/sadZhFkBLLm+gr55CQKC0nBgCSJXEyU9PmsGi1Li3)
password: ENC(MaF3AwiV/aXCCDMEx+nOgAtXreq62JMgRM+2M9NIpUe0vko3fahZ+IxnvocfaGnJ)
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
在启动类上加入 vm中 -Djasypt.encryptor.password=salt20220907
启动还是一样成功,这样就十分安全了。
此时记住,生成密文的代码改变了,因为3.0以下默认用的是PBEWithMD5AndDES加密,而3.0及以上用的是PBEWITHHMACSHA512ANDAES_256加密。
比如当版本是2.1.0时
加密代码将变成如下
public static void main(String[] args) {
StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
// 默认是PBEWithMD5AndDES加密
// 盐值
standardPBEStringEncryptor.setPassword("salt20220907");
// 加密明文
String encryptValue1 = standardPBEStringEncryptor.encrypt("shenyun");
String encryptValue2 = standardPBEStringEncryptor.encrypt("shenyun20220907");
// 解密密文
String decryptValue = standardPBEStringEncryptor.decrypt("1PcipFvXoDg95eW3ZP1MOw==");
System.out.println(encryptValue1);
System.out.println(encryptValue2);
System.out.println(decryptValue);
}
其它步骤都和上面一样
千万千万注意,如果生成密文和版本错乱,那么可能会抛出下面错误!!!
Description:
Failed to bind properties under 'spring.datasource.password' to java.lang.String:
Reason: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.datasource.password' to java.lang.String
Action:
Update your application's configuration
可以参考我另外一篇文章:Spring Boot Jasypt 3.0.4 报错---算法加解密使用不一致