SpringBoot配置文件敏感信息加密方案
在SpringBoot Project中,会将一些敏感信息配置到application.yml/application.properties配置文件中(同样适用于Spring Cloud的各个微服务其实(微服务实例)本质就是一个SpringBoot
),例如数据库的用户名和密码、Redis的密码等。为了保证敏感信息的安全,我们需要将此类数据进行加密配置。
Jasypt方案
官网 http://www.jasypt.org/
以下实践在JDK21、SpringBoot3.3.0下成功验证,若你的JDK和SpringBoot版本有所差异,可能需要调整一些细节
pom.xml
引入依赖
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
加密你的敏感信息
public class TmpUtil {
public static void main(String[] args) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
//加密所需的秘钥(salt),解密敏感信息仍旧需要改值
textEncryptor.setPassword("ashe");
//要加密的敏感信息
String url = textEncryptor.encrypt("jdbc:mysql://${host}/${port}?serverTimezone=Asia/Shanghai");
String username = textEncryptor.encrypt("username");
String password = textEncryptor.encrypt("password");
String driver = textEncryptor.encrypt("com.mysql.cj.jdbc.Driver");
System.out.println("ENC("+url+")");
System.out.println("ENC("+username+")");
System.out.println("ENC("+password+")");
System.out.println("ENC("+driver+")");
System.out.println(textEncryptor.decrypt(username));
System.out.println(textEncryptor.decrypt(password));
}
}
application.yml填写加密后的密文
spring:
datasource:
url: ENC(xxxx)
username: ENC(xxxx)
password: ENC(xxxx)
driver-class-name: ENC(xxxx)
#jasypt:
# encryptor:
# password: ashe # 替换为你自己的密钥
# iv-generator-classname: org.jasypt.iv.NoIvGenerator
# algorithm: PBEWithMD5AndDES
Jasypt库所使用的默认加密算法为PBEWithMD5AndDES,其需要解密的内容需要用ENC()包裹(你可以自定义选择其他加密算法),如果在配置文件中直接展示你的秘钥,那么密文将很容易被解密出原文,因此一般不建议在配置文件中展示,而是通过启动脚本的方式来告诉Jasypt秘钥值,用以解密密文。
IDEA中本地启动设置VM Options
-Djasypt.encryptor.password=ashe -Djasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator -Djasypt.encryptor.algorithm=PBEWithMD5AndDES
Linux中的启动脚本
#!/bin/bash
# Start the application with the Jasypt encryptor password (replace with your actual start command)
java -Djasypt.encryptor.password=ashe -Djasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator -Djasypt.encryptor.algorithm=PBEWithMD5AndDES -jar your-application.jar
较低版本的jasypt似乎不需要显式指定iv-generator-classname和algorithm
Druid方案
略(不太推荐该方案加密敏感信息)
与Spring Cloud Vault方案类似,都是通过(启动项目时)手动配置Datasource bean来解密数据库密码对应密文的思路(以代替SpringBoot的自动配置)实现
当然,你也可以自定义一种加密方式,然后在手动配置Datasource bean的时候解密密文即可。
变量方案
对于配置文件中的敏感信息value通过变量名代替,在启动脚本中传递该变量key对应的value
例如application.yml文件
spring:
datasource:
url: jdbc:mysql://host/port?serverTimezone=Asia/Shanghai
username: username
password: ${database_password}
driver-class-name: com.mysql.cj.jdbc.Driver
对应启动脚本
#!/bin/bash
# ashe为你的数据库密码原文
java -Ddatabase_password=ashe -jar your-application.jar
加密的敏感信息比较繁多时,推荐Jasypt方案
加密的敏感信息较少,推荐变量方案(不引入任何额外依赖)