大家好,我是神韵,是一个技术&生活博主。出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己。二是希望我的文章可以帮到大家。欢迎来点赞打卡,你们的行动将是我无限的动力。
本篇主题是:SpringBoot 之 Jasypt 实现yml配置文件加密
目录
在我们的项目中各种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 报错---算法加解密使用不一致