Jasypt加密
- Jasypt加密
- 引言
- 介绍
- 整合SpringBoot
-
- 引入依赖
- 编写配置
- 加密和解密
-
- 通过Java程序获取密文和解密
- 通过jasypt中jar包程序获取密文
- 使用密文:ENC(密文)
- 异常问题
-
- JCE权限问题
- yml中带有@引起的问题
- 关于盐值(密钥)配置设置
- 其他
Jasypt加密
引言
Jasypt也即Java Simplified Encryption
是Sourceforge.net
上的一个开源项目。Jasypt 1.4的新特性包括:加密属性文件(encryptable properties files)、Spring Framework集成、加密Hibernate数据源配置、新的命令工具、URL加密的Apache wicket集成以及升级文档。
根据Jasypt文档,该技术可用于加密任务与应用程序,例如:加密密码、敏感信息和数据通信、创建完整检查数据的sums、其他性能包括高安全性、基于标准的加密技术、可同时单向和双向加密的加密密码、文本、数字和二进制文件。Jasypt也可以与Acegi Security 整合也即Spring Security。Jasypt亦拥有加密应用配置的集成功能,而且提供一个开放的API从而任何一个Java Cryptography Extension都可以使用Jasypt。
Jasypt还符合RSA标准的基于密码的加密,并提供了无配置加密工具以及新的、高可配置标准的加密工具。
官网:http://www.jasypt.org/
介绍
配置信息只有 jasypt.encryptor.password
是必须的,配置项有:
- 注意:
- jasypt.encryptor.saltGeneratorClassname新版和旧版属性不一致
- jasypt.encryptor.algorithm加密算法不一致
1️⃣旧版
key | REQUIRED | DEFAULT VALUE |
---|---|---|
jasypt.encryptor.password | True | - |
jasypt.encryptor.algorithm | FALSE | PBEWithMD5AndDES |
jasypt.encryptor.keyObtentionlterations | FALSE | 1000 |
jasypt.encryptor.poolSize | FALSE | 1 |
jasypt.encryptor.providerName | FALSE | SunJCE |
jasypt.encryptor.providerClassName | FALSE | null |
jasypt.encryptor.saltGeneratorClassname | FALSE | org.jasypt.salt.RandomSaltGenerator |
jasypt.encryptor.ivGeneratorClassname | FALSE | org.jasypt.salt.NoOplVGenerator |
jasypt.encryptor.stringOutputType | FALSE | base64 |
jasypt.encryptor.proxyPropertySources | FALSE | false |
2️⃣新版
key | REQUIRED | DEFAULT VALUE |
---|---|---|
jasypt.encryptor.password | True | - |
jasypt.encryptor.algorithm | FALSE | PBEWITHHMACSHA512ANDAES_256 |
jasypt.encryptor.key-obtention-iterations | FALSE | 1000 |
jasypt.encryptor.pool-size | FALSE | 1 |
jasypt.encryptor.provider-name | FALSE | SunJCE |
jasypt.encryptor.provider-class-name | FALSE | null |
jasypt.encryptor.salt-generator-classname | FALSE | org.jasypt.salt.RandomSaltGenerator |
jasypt.encryptor.iv-generator-classname | FALSE | org.jasypt.iv.RandomIvGenerator |
jasypt.encryptor.string-output-type | FALSE | base64 |
jasypt.encryptor.proxy-property-sources | FALSE | false |
jasypt.encryptor.skip-property-sources | FALSE | empty list |
3️⃣需要注意加解密的类型一致
2.1.2版本默认加密方式为:PBEWithMD5AndDES
3.0.3版本默认加密方式为:PBEWITHHMACSHA512ANDAES_256
当引入3.0.3依赖,却没有添加相关jasypt加解密配置,而密文通过【PBEWithMD5AndDES】来加密,启动会报错。
需要切换为【PBEWITHHMACSHA512ANDAES_256】方式进行。
整合SpringBoot
引入依赖
<!-- 方式1:引入 jasypt-spring-boot-starter -->
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!-- 方式2:引入 jasypt-spring-boot 需在启动类添加@EnableEncryptableProperties -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>2.0.0</version>
</dependency>
编写配置
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES # 加密算法
password: cf150b74e4824146ad76e9ebe757ba76 # 使用加密密钥
加密和解密
通过Java程序获取密文和解密
@Autowired
private StringEncryptor stringEncryptor;
@Test
public void test() {
String secret = stringEncryptor.encrypt("root");
String decrypt = stringEncryptor.decrypt(secret);
System.out.println("password明文:" + decrypt);
System.out.println("password密文:" + secret);
}
/**
* StandardPBEStringEncryptor对象的setPassword方法设置盐值(密钥)
*/
@Test
public void test(){
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("hello");//设置加密盐值
String secret = stringEncryptor.encrypt("root");
String decrypt = stringEncryptor.decrypt(secret);
System.out.println("password明文:" + decrypt);
System.out.println("password密文:" + secret);
}
- 自己封装的工具类
/**
* Jasypt加密解密工具类
*/
public class JasyptUtil {
private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";
/**
* @param text 待加密原文
* @param crack 盐值(密钥)
* @return 加密后的字符串
* @Description: Jasypt加密(PBEWithMD5AndDES)
*/
public static String encryptWithMD5(String text, String crack) {
//1.创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
//2.加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(crack);
encryptor.setConfig(config);
//3.加密
return encryptor.encrypt(text);
}
/**
* @param text 待解密原文
* @param crack 盐值(密钥)
* @return 解密后的字符串
* @Description: Jasypt解密(PBEWithMD5AndDES)
*/
public static String decryptWithMD5(String text, String crack) {
//1.创建加解密工具实例
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
//2.加解密配置
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(PBEWITHMD5ANDDES);
config.setPassword(crack);
encryptor.setConfig(config);
//解密
return encryptor.decrypt(text);
}
/**
* @param text 待加密的原文
* @param crack 盐值(密钥)
* @return 加密后的字符串
* @Description: jasypt 加密(PBEWITHHMACSHA512ANDAES_256)
*/
public static String encryptWithSHA512(String text, String crack) {
//1.创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
//2.加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(crack);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 为减少配置文件的书写,以下都是 Jasypt 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(text);
}
/**
* @param text 待解密原文
* @param crack 盐值(密钥)
* @return 解密后的字符串
* @Description: jasypt 解密(PBEWITHHMACSHA512ANDAES_256)
*/
public static String decryptWithSHA512(String text, String crack) {
//1.创建加解密工具实例
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
//2.加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(crack);
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
// 为减少配置文件的书写,以下都是 Jasypt 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(text);
}
}
通过jasypt中jar包程序获取密文
1️⃣添加依赖,下载好jar包到本地maven仓库后,cmd进入jasypt.jar包所在的目录
如个人本地目录:D:\Java\mvn_repository\org\jasypt\jasypt\1.9.3
2️⃣加密命令,参数说明:
- input:需要加密的字段
- password:加密盐值,用来进行加密
- algorithm:加密方式,默认不写也行
命令:java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="root" password=hello algorithm=PBEWithMD5AndDES
# 输出
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.171-b11
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: root
password: hello
----OUTPUT----------------------
muiQcX1aXcMACgnq57hDDA==
3️⃣解密命令
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="aCEx6r9g2lBuGF8w/XU8wQ==" password=hello algorithm=PBEWithMD5AndDES
#输出
----ENVIRONMENT-----------------
Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.171-b11
----ARGUMENTS-------------------
algorithm: PBEWithMD5AndDES
input: muiQcX1aXcMACgnq57hDDA==
password: hello
----OUTPUT----------------------
root
使用密文:ENC(密文)
1️⃣如:数据库连接加密
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: ENC(muiQcX1aXcMACgnq57hDDA==) # 明文=root
2️⃣重要内容加密
my:
username: ENC(muiQcX1aXcMACgnq57hDDA==) # 明文=root
password: ENC(muiQcX1aXcMACgnq57hDDA==) # 明文=root
异常问题
JCE权限问题
org.jasypt.exceptions.EncryptionOperationNotPossibleException: 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
# 解决方案:
查看是否是加解密类型不一致导致。
或者下载:https://www.oracle.com/java/technologies/javase-jce8-downloads.html
下载压缩包解压,将local_policy.jar和US_export_policy.jar替换(或粘贴进去)D:\Java\JDK8\jre\lib\security\路径下的jar包
yml中带有@引起的问题
yml中@是特殊字符, 含有@左右需要加单引号。
jasypt 自动加密整个文件的时候,会将单引号也当做密码的一部分,这样得到的密文肯定是错的。
#解决方案:
直接将密码生成,然后再复制过去,不要带双引号。
关于盐值(密钥)配置设置
-
存放位置
- 工程内配置文件中
- 内部代码中
- 存放本地某处目录下的本地文件中
-
传入盐值
-
盐值明文存放到工程内配置文件存在安全风险。
-
存放本地某处目录下的本地文件中(推荐)
-
存放内部代码中。
-
在程序启动时,配置参数传入。
-
1️⃣在程序启动时,配置参数传入。
- 通过启动时传入密钥【Add VM options】
-Djasypt.encryptor.password=cf150b74e4824146ad76e9ebe757ba76
2️⃣命令行启动jar包时,传入命令
其他
- 不自定义加密类的话,默认算法为 PBEWithMD5AndDES
- 多次生成,每次生成的密码不一样。不同的密码序列,解密却可以一样。
- ENC前缀可改变,即自定义格式:需要添加配置
jasypt:
encryptor:
property:
prefix: "P["
suffix: "]"
my:
username: P[muiQcX1aXcMACgnq57hDDA==] # 明文=root
password: P[muiQcX1aXcMACgnq57hDDA==] # 明文=root