本节目标
- 了解Jasypt做什么用的
- 使用Jasypt
- 几种设置Jasypt盐值的方式
本节项目:在springboot + mybatis plus + 多数据源 + p6spy + Jasypt
Jasypt简介
Jasypt主要是用于在配置文件中,对敏感数据进行加密用的。比如:数据库的连接密码、第三方 Apikey、云服务商的 secretKey等等。
集成Jasypt
参照gitee.com/mayuanfei/S…下的springboot06项目创建springboot07项目。然后在其基础上进行修改。目标是,对现有配置文件中数据库的用户名和密码进行加密。
0. 在其基础上修改
这里说说怎么在springboot06项目基础上快速搭建springboot07项目。
-
原始项目目录中拷贝springboot06项目
-
把springboot06的副本改名称为springboot07
-
修改springboot07目录中的springboot06.iml文件名
-
在idea中能看到springboot07项目
但是此时还没有加入maven项目中管理。
-
pom文件中把springboot06修改为springboot07
-
idea的maven中添加springboot07项目
-
修改项目包名
-
修改Springboot06Application启动类名称
和上面相同的方式修改启动类名称为Springboot07Application
1. SpringBoot三板斧之加入依赖
<!-- Jasypt -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!-- 加密包 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
说明
如果使用默认的加密提供类,不需要加入下面的加密包的。这里说的默认加密提供其实就是JDK包中rt.jar包中sun.security.provider中的加密算法。但是如果想使用国密、AES256等加密算法,那么这个加密包还是必须的。
2. SpringBoot三板斧之添加配置
# Jasypt配置
jasypt:
encryptor:
# 秘钥
password: 123456
3. 进行测试
@SpringBootTest
public class JasyptTest {
@Resource
private StringEncryptor stringEncryptor;
@Test
//加密后的字符串:JgoBuHD89D4mLiAgtSQ6yg+kAdVc2I35WkTl44hGjfy832UGNtZJyn2fsEGsbehK
public void testEncrpt() {
String encrypt = this.stringEncryptor.encrypt("123456");
Console.log("加密后的字符串:{}", encrypt);
}
@Test
//解密后的字符串:123456
public void testDecrypt() {
String encrypt = "JgoBuHD89D4mLiAgtSQ6yg+kAdVc2I35WkTl44hGjfy832UGNtZJyn2fsEGsbehK";
String decrypt = this.stringEncryptor.decrypt(encrypt);
Console.log("解密后的字符串:{}", decrypt);
}
}
说明:
- 通过测试类,可以把要加密的原始字符串进行加密的。
- 同一个字符串,每次加密出来也是不一样的。
4. 修改配置文件
这里Jasypt模块有个前缀和后缀。ENC(中间是加密后的内容)。
spring:
datasource:
dynamic:
# 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: true
# 严格模式 匹配不到数据源则报错
strict: true
# 设置主库.也就是默认操作的数据库
primary: mysql
datasource:
# mysql数据源
mysql:
url: jdbc:mysql://192.168.0.1:3306/springboot-demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: ENC(/IjGBG1dthIsPXj9BlHdSXuqQyxLOoYni0z/9vSWbyAvQxhkVq/eWhrbi7D0sGAc)
# oracel数据源
oracle18:
url: jdbc:oracle:thin:@192.168.0.2:1521/test
username: ENC(fPIEFtxbGPIBLZo7shsEFbFc8Ch+2Y92l92PvwFRfHOypwPv9COv+0QdxpmCDi/C)
password: ENC(mn8glmWx+FGNX2RzNsccDAHtqkdykyaQKmU/0FG7JX1IH5Aba2q7XT3p0Xx9BJ+T)
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
oracle183:
url: jdbc:oracle:thin:@192.168.0.3:1521/orcl
username: ENC(mQq5f1ElDGKNaMpYLjNL3HB1XS9syTJVtUMW3hlSbKFhWZtGf3I2AgyX9qeaDWYQ)
password: ENC(MYV5caeE7p798/n9rhFOBR49F8xQGfPQ8bAwaSs/I1zG41kd/NB1F4dLv5zvVEhT)
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
# 全局hikariCP配置
hikari:
# 最大连接池数量
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 连接测试query(配置检测连接是否有效)
connectionTestQuery: SELECT 1
# 多久检查一次连接的活性
keepaliveTime: 30000
5. 集成完毕
通过简单的一个依赖引入+一个简单的配置,就可以无感使用这个加解密了。配置文件的内容,在使用前就会自动被解密,所以,可以看到我们上课的测试回滚的例子key正常的使用。
Jasypt的配置项
这里是官方给的配置图,从图中可以很明显的看到,除了password为,其他都是可选的。
生成密文的几种方式
1. 在springboot中生成密文
在继承Jasypt中的3.进行测试中已经描述过如何生成密文了
2. 自己写一个主测试类
public class JasyptMainTest {
// 写一个测试类打印Jasypt所有支持的算法
public static void getJasyptAllAlgorithmNames() {
Set algorithms = AlgorithmRegistry.getAllPBEAlgorithms();
for (Object algorithm : algorithms) {
System.out.println(algorithm);
}
System.out.println("============================");
Set allDigestAlgorithms = AlgorithmRegistry.getAllDigestAlgorithms();
for (Object algorithm : allDigestAlgorithms) {
System.out.println(algorithm);
}
}
public static void main(String[] args) {
getJasyptAllAlgorithmNames();
PooledPBEStringEncryptor stringEncryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("123456"); // 秘钥
// 以下是Jasypt3.x版本默认配置
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
stringEncryptor.setConfig(config);
// 测试加解密
String original = "laoma";
String encrypted = stringEncryptor.encrypt(original);
String decrypted = stringEncryptor.decrypt(encrypted);
System.out.println("Original: " + original);
System.out.println("Encrypted: " + encrypted);
System.out.println("Decrypted: " + decrypted);
// 另外一种更简便的方式进行加密
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("123456");
textEncryptor.encrypt(original);
encrypted = stringEncryptor.encrypt(original);
decrypted = stringEncryptor.decrypt(encrypted);
System.out.println("Original: " + original);
System.out.println("Encrypted: " + encrypted);
System.out.println("Decrypted: " + decrypted);
}
}
说明:这个测试方法中还包括查看现在Jasypt中支持的算法。
getAllPBEAlgorithms
PBE(Password-Based Encryption):代表基于密码的加密。可逆的算法
getAllDigestAlgorithms:
Digest:这里翻译为摘要,它是一种将任意长度的输入数据映射到固定长度输出的过程,输出通常称为哈希值、哈希码、哈希和、校验和、消息摘要、数字指纹或简称哈希。不可逆算法
3. 采用Jasypt的maven插件
-
加入maven插件
<!-- 在plugins标签中加入 --> <!-- Jasypt的maven插件 --> <plugin> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-maven-plugin</artifactId> <version>3.0.5</version> </plugin> -
在idea的终端中执行命令
mvn jasypt:encrypt-value -Djasypt.encryptor.password="123456" -Djasypt.plugin.value="laoma" -
解密
mvn jasypt:decrypt-value -Djasypt.encryptor.password="123456" -Djasypt.plugin.value="3fDX6rbJbe6URmf9bCR0iVNAF05231FGs3HRmoc+Ti6c4qQbHIseFHjFGpLj7Mt9"
秘钥存放的方式
1. 在配置文件中
# Jasypt配置
jasypt:
encryptor:
# 秘钥
password: 123456
这样能获得配置文件的人就能知道密钥,不够安全。但它是一种方便简单的方式。不被推荐的一种方式。
2. 在运行时参数中
在启动Java程序时加参数:-Djasypt.encryptor.password=pkslow,这样就不会把密钥放在代码中去了。
这里拿idea举例:
在实际部署时运行,类似如下命令行语句:
java -jar -Djasypt.encryptor.password=123456 xxx.jar
3. 在系统环境变量中
把密钥放在linux系统的环境变量中去,只有能拿到服务器访问权限的人,才有可能知道密钥在哪。例如:
# 配置profile文件
export JASYPT_PASSWORD = 123456
# 生效
source /etc/profile
# 运行java程序时
java -jar -Djasypt.encryptor.password=${JASYPT_PASSWORD} xxx.jar
或者在配置文件中加入秘钥设置
jasypt:
encryptor:
password: ${JASYPT_PASSWORD}
4. 自定义加密
Jasypt在SpringBoot环境中默认找的加密bean如下:
所以我们自定义加密bean,为了能够覆盖默认的,也叫这个名字,代码如下:
@Configuration
public class JasyptConfig {
@Bean("jasyptStringEncryptor")
public StandardPBEStringEncryptor jasyptStringEncryptor() {
StandardPBEStringEncryptor stringEncryptor = new StandardPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("123456"); // 秘钥
// 以下是Jasypt3.x版本默认配置
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
stringEncryptor.setConfig(config);
return stringEncryptor;
}
}
有了这个配置文件,就不用在yaml中配置Jasypt的相关信息了。密码在类中,除非反编译,否则看不到秘钥。
自定义前后缀
Jasypt默认的加密前缀是以:ENC(开头的;后缀:),如下所示:
password: ENC(/IjGBG1dthIsPXj9BlHdSXuqQyxLOoYni0z/9vSWbyAvQxhkVq/eWhrbi7D0sGAc)
如果修改成自己希望的前后缀,可以修改如下:
#jasypt:
jasypt:
encryptor:
property:
prefix: LM(
suffix: )
这样就能定义自己的前后缀了,配置后,如下所示:
password: LM(/IjGBG1dthIsPXj9BlHdSXuqQyxLOoYni0z/9vSWbyAvQxhkVq/eWhrbi7D0sGAc)
代码地址
gitee.com/mayuanfei/S…下的springboot07
记忆印记
- 知道 Jasypt在什么场景下用
- SpringBoot如何集成Jasypt
- Jasypt的秘钥如何能更安全
- Jasypt生成秘钥的方式
- Jasypt自定义前后缀