场景

公司要求配置文件中所有密码不以明文形势显示。
通常有2种方案:
1、集成jasypt进行加密。
2、使用配置中心统一管理。
这里说下jasypt加密。

过程

pom.xml引入依赖

有2种方式可以实现。

引入 jasypt-spring-boot-starter

这种不用加@EnableEncryptableProperties

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>

引入 jasypt-spring-boot

需要加@EnableEncryptableProperties

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>2.0.0</version>
</dependency>

推荐第一种,毕竟少一点配置。

配置文件中添加密钥

yml和properties中配置文件分别如下:

jasypt:
encryptor:
password: abc123

jasypt.encryptor.password=abc123

配置文件中将需要加密的字符串用 ENC() 括起来

这一步需要先生成密文,然后再填入,ENC中的是密文。
如:

spring.datasource.password= ENC(MazBcy1F0QG6AwLwhkaPkg==)

自定义工具类代码

如果直接执行main方法,一定要保证password和配置文件中的jasypt.encryptor.password一致,否则结果肯定不同。

@Component
public class JasyptUtils {
private static Logger logger = LoggerFactory.getLogger(JasyptUtils.class);

@Autowired
StringEncryptor encryptor;

// 加密
public String getEncryptResult(String string) {
String encryptResult = encryptor.encrypt(string);
logger.info("原字符串:{} ,加密后字符串: {}",string,encryptResult);
return encryptResult;
}

// 解密
public String getDecryptResult(String string) {
String decryptResult = encryptor.decrypt(string);
logger.info("加密后字符串:{} ,原字符串: {}",string,decryptResult);
return decryptResult;
}

public static void main(String[] args) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("abcxyz"); // 相当于密钥加盐,这个要和配置文件一致
String string="1234";
String encryptResult = encryptor.encrypt(string);
logger.info("原字符串:{} ,加密后字符串: {}",string,encryptResult);

String string2="KyyuLbN5UGc02OArDKNVMA==";
String decryptResult = encryptor.decrypt(string2);
logger.info("加密后字符串:{} ,原字符串: {}",string2,decryptResult);
}
}

提示:Encryptor config not found for property jasypt.encryptor.algorithm, using default value: PBEWithMD5AndDES

这个没关系,如果不自定义加密类的话,默认算法为 PBEWithMD5AndDES
这句其实相当于

encryptor.setAlgorithm("PBEWithMD5AndDES");

多次生成,每次生成的密码一样么

肯定不一样,每次生成密码都是不同的。
但是不同的密码序列,解密却可以一样。

jasypt-spring-boot-starter 与spring-boot-starter版本的对应

在自己的测试项目上,2.0.0没有问题,但是到了生产项目就报错。 多半是版本不一致的问题。

解决方案

找到符合对应springboot的版本。
有的时候会发现,版本并不严格按照依赖关系。 例如我的项目是spring是1.5.9 ,按道理说不支持1.18,但是实测能用。
原因是,版本依赖是保证一定能用的。 如果某个功能,恰好不在版本的变动范围内,也就是说虽然版本不对应,但是该功能正好2个都支持, 那么也是没问题的,但毕竟有风险。

常用的版本对照关系

jasypt-spring-boot-starter

依赖的 spring-boot-starter

2.1.0

2.0.3.RELEASE 2.2.6.RELEASE

2.0.0

2.0.0.RELEASE 2.2.6.RELEASE

1.18

1.5.10.RELEASE 2.2.6.RELEASE

1.12

1.5.1.RELEASE 2.2.6.RELEASE

1.5 | 官网为空,实测报stackover flow错误

很明显1.12范围更广。用这个就不错。
但是也不是版本越低越好,1.5实测报错。所以选个合适的就行。

引入依赖的时候,最后放在spring*starter后面

虽然不知道为什么,但是总感觉这样更稳妥一些。

生成的密码后面没有==号是正常的么

这个是正常的。 有的会带有 ‘’ 有的不带。
但是都是正确的密码。
实测如果string短,一般会带’
’,如果长一点一般,不带。

yml中带有@引起的问题

yml中@是特殊字符, 所以如果含有@ 左右需要加单引号。
但是jasypt 自动加密整个文件的时候,会将单引号也当做密码的一部分,这样得到的密文肯定是错的。
解决方案:
直接将密码生成,然后再复制过去,不要带双引号。

密码是否不对

ORA-01017: invalid username/password; logon denied

这个表示密码不对

如果是账户已经被锁定等,说明密码没错。

maven官网jasypt地址,可以看每个版本的依赖:
​​​https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter​