网站首页 > java教程 正文
一、前言
最新公司为了提高代码安全性,要求数据库,kakfa,redis的连接不能直接明文配置。找了很多方案最终发现这个jasypt-spring-boot组件,但也被这个组件坑炸了,为什么呢?因为出现死锁的问题。线上直接P0级别事故,现在我们来复盘一下这个死锁问题。首先分享一下如何集成这个组件。
二、如何集成
1、引入jasypt-spring-boot加密组件的starter(特别说明出现死锁的版本:3.0.3)
com.github.ulisesbocchio
jasypt-spring-boot-starter
3.0.4
2、jasypt常用参数说明
2.1、algorithm与iv-generator-classname对应关系
algorithm | iv-generator-classname | 版本 |
PBEWithMD5AndDES | org.jasypt.iv.NoIvGenerator | 3.0.0已下版本 |
PBEWITHHMACSHA512ANDAES_256 | org.jasypt.iv.RandomIvGenerator | 3.0.0以上版本 |
如果对应错误启动的时候会报以下错误
Failed to bind properties under 'xxx.xxx.xxx' to java.lang.String
2.2、配置说明
#自定义加密密钥,对配置文件里的重要项进行加密
jasypt:
encryptor:
password: xiao #加密算法密钥
property:
prefix: ENC( #算法识别前缀,加密后的账号密码需要用这个包起来
suffix: ) #算法识别后缀
algorithm: PBEWITHHMACSHA512ANDAES_256 #默认加密算法
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
algorithm加密算法要与IvGeneratorClassName对应的值配套
2、正常的明文配置文件yml(安全级别为0)
server:
port: 10000
spring:
application:
name: xixien
datasource:
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
3、通过工具类生成加密后的账号,密码
package com.xixien.api.base.utils;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
public class JasyptUtils {
public static void main(String[] args) {
String username = encrypt("root");
String password = encrypt("123456");
System.out.println("加密后的账号:"+username);
System.out.println("加密后的密码:"+password);
System.out.println("加密前的账号:"+decrypt(username));
System.out.println("加密前的密码:"+decrypt(password));
}
/**
* 加密
* @param plaintext 明文密码
*
*/
public static String encrypt(String plaintext) {
//加密工具
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
//加密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
// 算法类型
//config.setAlgorithm("PBEWithMD5AndDES");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
//生成秘钥的公钥
config.setPassword("xiao");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
//应用配置
encryptor.setConfig(config);
//加密
return encryptor.encrypt(plaintext);
}
/**
* 解密
*
* @param ciphertext 待解密秘钥
*
*/
public static String decrypt(String ciphertext) {
//加密工具
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
//加密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
//config.setAlgorithm("PBEWithMD5AndDES");
//生成秘钥的公钥
config.setPassword("xiao");
//加密算法要与IvGeneratorClassName对应的值配套
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
//应用配置
encryptor.setConfig(config);
//解密
return encryptor.decrypt(ciphertext);
}
}
main行数运行结果
替换名为配置
原来的明文密码值,改为 ENC(xxx) ,其中xxx是密文。
server:
port: 10000
spring:
application:
name: xixien
datasource:
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: ENC(9dGDBltW5Q9ealpUkaoEQyup4CSDr7Gz+CKpat3Uq99Wwaz7In4PyKKPSJOs+stK)
password: ENC(q1KCCS7dSI1eznFC9i7ml3cuGRPjhXYswqkgJWAffMJlkS1I4E35GiQqsv8gHYpx)
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#自定义加密密钥,对配置文件里的重要项进行加密
jasypt:
encryptor:
password: xiao #加密算法密钥(例子我们放这里)
property:
prefix: ENC( #算法识别前缀,加密后的账号密码需要用这个包起来
suffix: ) #算法识别后缀
algorithm: PBEWITHHMACSHA512ANDAES_256 #默认加密算法
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
自定义加密前后缀:
默认前缀prefix=ENC( 后缀 suffix= ) 这个可以自己随心所欲的替换比如LOL()
jasypt:
encryptor:
property:
prefix: LOL( #算法识别前缀,加密后的账号密码需要用这个包起来
suffix: )
看完这些你是否思考了
三、如何更安全
1、使用自定义加密器
下面是一个自定义加密器bean,可以看到除了一些在yml文件中配置的属性还多了配置(加上了注释的代码),源码类
JasyptEncryptorConfigurationProperties中有些默认配置
@Configuration
public class XiaoXiongEncryptorCfg {
//默认bean为jasyptStringEncryptor
@Bean( name = "xiaoXiongEncryptorBean" )
public StringEncryptor xiaoXiongEncryptorBean() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("xiao");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
//源码默认值
config.setKeyObtentionIterations("1000");
//源码默认值
config.setPoolSize("1");
//源码默认值
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
//源码默认值
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
2、密钥不放在配置文件中
- 方式一:直接作为程序启动时的命令行参数来带入
java -jar project.jar --jasypt.encryptor.password=xiao
- 方式二:直接作为程序启动时的应用环境变量来带入
java -Djasypt.encryptor.password=xiao -jar project.jar
- 方式三:甚至可以作为系统环境变量的方式来带入
比方说,我们提前设置好系统环境变量JASYPT_ENCRYPTOR_PASSWORD = xiao,则直接在Spring Boot的项目配置文件中做如下配置即可:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD}
死锁
我线上的某个业务触发了这个死锁。程序表现为假死,最后通过分析堆栈日志找到这个死锁。也在github上第277的issues发现了端倪。真是脑裂呀
https://github.com/ulisesbocchio/jasypt-spring-boot/issues/277
1、原因
2、修改后的代码
猜你喜欢
- 2025-03-24 虾皮二面:MySQL 中有哪些锁?表级锁和行级锁有什么区别?
- 2025-03-24 Java三种方式实现redis分布式锁(java 实现redis分布式锁)
- 2025-03-24 java编程开发经常遇到的十个问题(java编程遇到的问题及解决办法)
- 2025-03-24 线程池误用导致系统假死(线程池爆了)
- 2025-03-24 如何编写高效的Java代码(写java代码的步骤)
- 2025-03-24 Java多线程编程的7个致命陷阱90%的程序员都在第3个坑里疯狂加班
- 2025-03-24 什么是死锁?如何避免死锁?(什么是死锁?用什么方法实现死锁的避免?)
- 2025-03-24 Java进程突然失去响应的原因排查(java进程崩溃)
- 2025-03-24 Java面试题及答案最全总结(2025版)
- 2025-03-24 多线程场景下,什么情况会发生死锁?该如何避免死锁?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)