jasypt 配置文件加解密
一.简要描述
- Spring boot配置文件中的用户名密码等配置文件一般情况下是明文保存的,这样就隐藏了密码泄露的安全隐患,所以一般都要求将密码加密后保存配置的,我们可以使用 jasypt 对 Springboot 应用中的密码进行加密。
二.引入 maven 依赖
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
三.密码原文加密
1. 采用 cmd 命令行方式加密解密
从本地maven库中找到jar包
.m2\repository\org\jasypt\jasypt\1.9.3
1.1 常用参数:
- input: 密码原文
- password: 加解密秘钥
- algorithm: 采用的算法
- ivGeneratorClassName: 生成器类名
- keyObtentionIterations: 迭代次数, 默认 1000
1.2 执行 cmd 加解密命令
比如用户名和密码分别是 root 和 123zxcv
1.2.1 采用算法 PBEWITHHMACSHA512ANDAES_256 执行加密命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=haha algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
E:\>java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123zxcv" password=haha algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09
----ARGUMENTS-------------------
ivGeneratorClassName: org.jasypt.iv.RandomIvGenerator
algorithm: PBEWITHHMACSHA512ANDAES_256
input: 123zxcv
password: haha
keyObtentionIterations: 10000
----OUTPUT----------------------
/t8E+snZ4ODAwQU9gj0eA6MRnL98PHEGJVtOYN44wzmNKqHrY0TciomqfQg2qb2w
OUTPUT输出参数则为密文
1.2.2 采用算法 PBEWithMD5AndDES 执行加密命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=haha algorithm=PBEWithMD5AndDES ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
E:\>java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=haha algorithm=PBEWithMD5AndDES ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09
----ARGUMENTS-------------------
ivGeneratorClassName: org.jasypt.iv.RandomIvGenerator
algorithm: PBEWithMD5AndDES
input: root
password: haha
keyObtentionIterations: 10000
----OUTPUT----------------------
gf0gosWSje2GwnF6KWKHbaUDeI1PLo1K
1.3 执行解密命令
1.3.1 采用算法 PBEWITHHMACSHA512ANDAES_256 执行解密命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="/t8E+snZ4ODAwQU9gj0eA6MRnL98PHEGJVtOYN44wzmNKqHrY0TciomqfQg2qb2w" password=haha algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
E:\>java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="/t8E+snZ4ODAwQU9gj0eA6MRnL98PHEGJVtOYN44wzmNKqHrY0TciomqfQg2qb2w" password=haha algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09
----ARGUMENTS-------------------
ivGeneratorClassName: org.jasypt.iv.RandomIvGenerator
algorithm: PBEWITHHMACSHA512ANDAES_256
input: /t8E+snZ4ODAwQU9gj0eA6MRnL98PHEGJVtOYN44wzmNKqHrY0TciomqfQg2qb2w
password: haha
keyObtentionIterations: 10000
----OUTPUT----------------------
123zxcv
1.3.2 采用算法 PBEWithMD5AndDES 执行解密命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="gf0gosWSje2GwnF6KWKHbaUDeI1PLo1K" password=haha algorithm=PBEWithMD5AndDES ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
E:\>java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="gf0gosWSje2GwnF6KWKHbaUDeI1PLo1K" password=haha algorithm=PBEWithMD5AndDES ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator keyObtentionIterations=10000
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.201-b09
----ARGUMENTS-------------------
ivGeneratorClassName: org.jasypt.iv.RandomIvGenerator
algorithm: PBEWithMD5AndDES
input: gf0gosWSje2GwnF6KWKHbaUDeI1PLo1K
password: haha
keyObtentionIterations: 10000
----OUTPUT----------------------
root
2 java 代码加解密
package com.ashen.heihei.util;
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;
/**
* Jasypt加解密工具类
* @author HY
*/
public class JasyptUtil {
private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";
public static void main(String[] args) {
String secret1 = encryptWithMD5("root", "haha");
System.out.println(secret1);
String name1 = decryptWithMD5(secret1, "haha");
System.out.println(name1);
String secret2 = encryptWithMD5("123zxcv", "haha");
System.out.println(secret2);
String name2 = decryptWithMD5(secret2, "haha");
System.out.println(name2);
}
/**
* jasypt 加密(PBEWithMD5AndDES)
* @param message 待加密的原文
* @param password 加解密秘钥
* @return
*/
public static String encryptWithMD5(String message, String password) {
// 1. 创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
// 2. 加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(password);
// 设置迭代次数
config.setKeyObtentionIterations( "10000");
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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(message);
}
/**
* jasypt 解密(PBEWithMD5AndDES)
* @param encryptedMessage 待解密的原文
* @param password 加解密秘钥
* @return
*/
public static String decryptWithMD5(String encryptedMessage, String password) {
// 1. 创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
// 2. 加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(password);
// 设置迭代次数
config.setKeyObtentionIterations( "10000");
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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(encryptedMessage);
}
/**
* jasypt 加密 (PBEWITHHMACSHA512ANDAES_256)
* @param message 待加密的原文
* @param password 加解密秘钥
* @return
*/
public static String encryptWithSHA512(String message, String password) {
// 1. 创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
// 2. 加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(password);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 设置迭代次数
config.setKeyObtentionIterations( "10000");
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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(message);
}
/**
* jasypt 解密(PBEWITHHMACSHA512ANDAES_256)
* @param encryptedMessage 待解密的原文
* @param password 加解密秘钥
* @return
*/
public static String decryptWithSHA512(String encryptedMessage, String password) {
// 1. 创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
// 2. 加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(password);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 设置迭代次数
config.setKeyObtentionIterations( "10000");
// 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
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(encryptedMessage);
}
}
三.application.yaml配置
1. jasypt相关配置
几个重要的参数:
- password: 加解密秘钥,如果该秘钥泄露,加密后会被解密,应该通过环境变量或者启动参数传递,或者在代码内对该密钥解析二次加解密
- algorithm: 采用的算法,PBEWITHMD5ANDDES、PBEWITHMD5ANDTRIPLEDES、PBEWITHSHA1ANDDESEDE、PBEWITHSHA1ANDRC2_40、PBEWITHHMACSHA512ANDAES_256,对于 PBEWITHMD5ANDTRIPLEDES、PBEWITHHMACSHA512ANDAES_256 算法,需要在 JDK 中安装 JCE 扩展库
key-obtention-iterations: 迭代次数, 默认 1000
encryptor:
password: haha
algorithm: PBEWITHHMACSHA512ANDAES_256
key-obtention-iterations: 10000
2. 数据库密码配置
将密码加密后用ENC()将密文括起来,jasypt会自动解析,也可通过参数 prefix: “ENC@[” 和 suffix: “]“设置其他值
spring:
datasource:url: jdbc
//localhost:3306/heheda?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
username: root
password: 123zxcv
username: ENC(ANCT18nxVcrbxXc2niY7JBKK+4ORvGCgvEUBr4wobWn/QZjNlKLsYbuhnyHGx4lW)
password: ENC(tHJC+FMYPe12iwvIj+nJkc5Vks+fPAJ9sYe2utWabbYtToxnYwjsvWjPrid8hY6M)
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
dbcp2:
max-wait-millis: 10000
min-idle: 5
initial-size: 5
max-total: 100
配置后,直接启动 springboot 即可
四.秘钥 password 安全
- 上文说过加解密秘钥 password 秘钥泄露,加密后会被解密,有以下几种方式可以对秘钥进一步保护
1.password 加到 springboot 启动参数中
java -jar jasypt-demo.jar --jasypt.encryptor.password=haha
2.作为程序启动时的应用环境变量
java -Djasypt.encryptor.password=haha -jar jasypt-demo.jar
3.password 加到系统环境变量中
/etc/profile 中加入:
export JASYPT_ENCRYPTOR_PASSWORD=haha
jasypt:
encryptor:password: ${JASYPT_ENCRYPTOR_PASSWORD}
algorithm: PBEWITHHMACSHA512ANDAES_256
key-obtention-iterations: 10000
4. 取消配置, 采用内部配置
去掉 application.yaml 中的 jasypt 相关配置,采用 @Configuration 解析
package com.ashen.heihei.config;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/**
- jasypt 加解密配置
- @Author: HY
*/
@Configuration
public class JasyptConfig {
/**
* 加解密秘钥
*/
private static String PASSWORD = "haha";
/**
* 加密算法
*/
private static String ALGORITHM = "PBEWITHHMACSHA512ANDAES_256";
/**
* 迭代次数 iterations
*/
private static String ITERATIONS = "10000";
@Bean("jasyptStringEncryptor")
public PooledPBEStringEncryptor jasyptEncryptor(){
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(PASSWORD);
config.setAlgorithm(ALGORITHM);
config.setKeyObtentionIterations(ITERATIONS);
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
五.常见异常
1.Reason: Failed to bind properties under ‘spring.datasource.password’ to java.lang.String
- 有可能密文加密解密时采用的参数不一致导致,比如采用的算法不一样,秘钥不一样,或者迭代次数不一样
2.Encryption raised an exception. A possible cause is you are using strong encryption algorithms and you have not installed the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files in this Java Virtual Machine
原因是 jdk 的无限强度管辖权政策权限不够(JCE),下载一个JCE, 解压jar包,加入两个jce包替换jre下的 jdk/jre/lib/security/ 目录下权限包,
https://www.oracle.com/java/technologies/javase-jce8-downloads.html
springboot集成jasypt示例代码链接
还没有评论,来说两句吧...