在项目开发过程中,我们往往可以看到许多项目的配置文件中可以看到各种明文密码的情况,比如:数据库密码、Redis
连接密码等等一些敏感信息就这么赤裸裸的暴露在配置文件中,如果这些配置信息被图谋不轨的人拿到,那损失和后果就不堪设想。
之前倒是看到过一个例子,一个程序员把自己公司的项目代码上传到了自己的GitHub仓库里了,结果配置文件忘了处理,导致公司数据库泄露,关键问题是,这个公司还是个酒店管理公司,因此后果可想而知了(又要拆散多少对“恩爱”的夫妻)…
换个角度想,假如当时那个项目的配置文件里,所有重要信息都经过了加密,那这一幕大概率就不会发生了。所以,即使是项目的配置文件,重要的信息也得加密。
引入 jasypt-spring-boot
加密组件
JASYPT 官方 GitHub
地址
点击查看 那些不好好看官网更新日志,一言不合就提 Issues
的人
创建 Spring Boot
项目
配置主启动类采用 @SpringBootApplication
配置
引入 jasypt-spring-boot
组件(3.x
和 2.x
加密算法有变化)
<dependency>
<groupId>com.github.ulisesbocchiogroupId>
<artifactId>jasypt-spring-boot-starterartifactId>
<version>3.0.3version>
dependency>
<dependency>
<groupId>com.github.ulisesbocchiogroupId>
<artifactId>jasypt-spring-boot-starterartifactId>
<version>2.1.2version>
dependency>
在 Spring Boot
项目的配置文件中配置加解密的秘钥
jasypt.encryptor.password=xxxx@2020
在 Spring Boot
项目的配置文件中将需要加密的配置信息采用 ENC()
包裹即可
# 如下加密信息如何得到,请参考 第四大点的测试用例
spring.datasource.druid.password=ENC(KvET8AadJk8Ro25LK885WFWJIjXNYiAkQVBMezUe/sJCy/XK38PP0OpDsk81XswR)
以上配置即可完成敏感配置信息的加密全部过程
2.x
版本的分析
如果引入的是 2.x
的版本,启动信息如下:
String Encryptor custom Bean not found with name 'jasyptStringEncryptor'. Initializing Default String Encryptor
Encryptor config not found for property jasypt.encryptor.algorithm, using default value: PBEWithMD5AndDES
Encryptor config not found for property jasypt.encryptor.key-obtention-iterations, using default value: 1000
Encryptor config not found for property jasypt.encryptor.pool-size, using default value: 1
Encryptor config not found for property jasypt.encryptor.provider-name, using default value: null
Encryptor config not found for property jasypt.encryptor.provider-class-name, using default value: null
Encryptor config not found for property jasypt.encryptor.salt-generator-classname, using default value: org.jasypt.salt.RandomSaltGenerator
Encryptor config not found for property jasypt.encryptor.iv-generator-classname, using default value: org.jasypt.iv.NoIvGenerator
Encryptor config not found for property jasypt.encryptor.string-output-type, using default value: base64
通过以上信息的解读,我们可以了解到的信息如下:
默认加密算法:PBEWithMD5AndDES
默认的迭代次数: 1000
默认池大小: 1
默认生成盐的类:org.jasypt.salt.RandomSaltGenerator
默认IV
生成器类:org.jasypt.iv.NoIvGenerator
默认输出类型:base64
3.x
版本分析
如果引入的是 3.x
的版本,启动信息如下:
String Encryptor custom Bean not found with name 'jasyptStringEncryptor'. Initializing Default String Encryptor
Encryptor config not found for property jasypt.encryptor.algorithm, using default value: PBEWITHHMACSHA512ANDAES_256
Encryptor config not found for property jasypt.encryptor.key-obtention-iterations, using default value: 1000
Encryptor config not found for property jasypt.encryptor.pool-size, using default value: 1
Encryptor config not found for property jasypt.encryptor.provider-name, using default value: null
Encryptor config not found for property jasypt.encryptor.provider-class-name, using default value: null
Encryptor config not found for property jasypt.encryptor.salt-generator-classname, using default value: org.jasypt.salt.RandomSaltGenerator
Encryptor config not found for property jasypt.encryptor.iv-generator-classname, using default value: org.jasypt.iv.RandomIvGenerator
Encryptor config not found for property jasypt.encryptor.string-output-type, using default value: base64
通过以上信息的解读,我们可以了解到的信息如下:
默认加密算法:PBEWITHHMACSHA512ANDAES_256
默认的迭代次数: 1000
默认池大小: 1
默认生成盐的类:org.jasypt.salt.RandomSaltGenerator
默认IV
生成器类:org.jasypt.iv.RandomIvGenerator
默认输出类型:base64
通过如上信息的获取,我们即可编写测试工具,根据不同的版本和加密算法生成敏感信息的加密密文
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
/**
* @ClassName: JasypUtil
* @Description: Jasyp加解密工具类
* @Author: Rambo
* @CreateDate: 2020/7/13 10:12
* @UpdateUser: Rambo
* @UpdateDate: 2020/7/13 10:12
* @Version: 1.0.0
*/
public class JasypUtil {
private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";
/**
* @Description: Jasyp加密(PBEWithMD5AndDES)
* @Author: Rambo
* @CreateDate: 2020/7/13 10:24
* @UpdateUser: Rambo
* @UpdateDate: 2020/7/13 10:24
* @param plainText 待加密的原文
* @param factor 加密秘钥
* @return java.lang.String
* @Version: 1.0.0
*/
public static String encryptWithMD5(String plainText, String factor) {
// 1. 创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
// 2. 加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(factor);
encryptor.setConfig(config);
// 3. 加密
return encryptor.encrypt(plainText);
}
/**
* @Description: Jaspy解密(PBEWithMD5AndDES)
* @Author: Rambo
* @CreateDate: 2020/7/13 10:28
* @UpdateUser: Rambo
* @UpdateDate: 2020/7/13 10:28
* @param encryptedText 待解密密文
* @param factor 解密秘钥
* @return java.lang.String
* @Version: 1.0.0
*/
public static String decryptWithMD5(String encryptedText, String factor) {
// 1. 创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
// 2. 加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(factor);
encryptor.setConfig(config);
// 3. 解密
return encryptor.decrypt(encryptedText);
}
/**
* @Description: Jasyp 加密(PBEWITHHMACSHA512ANDAES_256)
* @Author: Rambo
* @CreateDate: 2020/7/25 14:34
* @UpdateUser: Rambo
* @UpdateDate: 2020/7/25 14:34
* @param plainText 待加密的原文
* @param factor 加密秘钥
* @return java.lang.String
* @Version: 1.0.0
*/
public static String encryptWithSHA512(String plainText, String factor) {
// 1. 创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
// 2. 加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(factor);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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);
// 3. 加密
return encryptor.encrypt(plainText);
}
/**
* @Description: Jaspy解密(PBEWITHHMACSHA512ANDAES_256)
* @Author: Rambo
* @CreateDate: 2020/7/25 14:40
* @UpdateUser: Rambo
* @UpdateDate: 2020/7/25 14:40
* @param encryptedText 待解密密文
* @param factor 解密秘钥
* @return java.lang.String
* @Version: 1.0.0
*/
public static String decryptWithSHA512(String encryptedText, String factor) {
// 1. 创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
// 2. 加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(factor);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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);
// 3. 解密
return encryptor.decrypt(encryptedText);
}
public static void main(String[] args) {
String factor = "xxxx@2020";
String plainText = "123456";
String encryptWithMD5Str = encryptWithMD5(plainText, factor);
String decryptWithMD5Str = decryptWithMD5(encryptWithMD5Str, factor);
String encryptWithSHA512Str = encryptWithSHA512(plainText, factor);
String decryptWithSHA512Str = decryptWithSHA512(encryptWithSHA512Str, factor);
System.out.println("采用MD5加密前原文密文:" + encryptWithMD5Str);
System.out.println("采用MD5解密后密文原文:" + decryptWithMD5Str);
System.out.println();
System.out.println("采用SHA512加密前原文密文:" + encryptWithSHA512Str);
System.out.println("采用SHA512解密后密文原文:" + decryptWithSHA512Str);
}
}