全栈老司机 程序员林中酒(公众号同名) 来啦
业务分析
在 Spring 框架中,数据库密码是敏感数据,需要妥善保管。如果数据库密码不加密,则存在以下风险:
- 攻击者可以通过恶意手段获取数据库密码,从而访问数据库。
- 开发人员或运维人员在配置数据库连接时,可能不小心将数据库密码泄露。
使用 Jasypt 加密数据库密码可以降低上述风险。Jasypt 提供了多种加密算法,可以有效保护数据库密码的安全。
其他密码也可以用这个来加密
代码
1.依赖
<!-- 配置文件密文工具 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
<!-- END配置文件密文 -->
2.配置yml文件
#jasypt加密配置
jasypt:
#加密设置
encryptor:
#加密密钥 比如 jaspyt_password
password: jaspyt_password
#加密算法 比如 PBEWITHHMACSHA512ANDAES_256
algorithm: PBEWITHHMACSHA512ANDAES_256
property:
#ENC[],包含在前后缀的加密信息,会使用指定算法解密
#前缀
prefix: "ENC@["
#后缀
suffix: "]"
3.工具类
package com.linzhongjiu.common.utils;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
/**
* 配置文件加密工具类
*/
public class JasyptUtil {
private static StringEncryptor stringEncryptor;
//加密的盐
private static String password = "jaspyt_password";
//加密算法
private static String algorithm = "PBEWITHHMACSHA512ANDAES_256";
// 要加密的明文密码
private static final String ENCRYPT_PASS = "enpass";
// 待解密的密文密码
private static final String DECRYPT_PASS = "UINFs6Pu3big8+FcfBlLB7DhmMnCViCwCsmnjVl6Zmmt+UJBjieM9WMIiH2nFIMR";
public static void main(final String[] args) {
// 待加密的明文密码
try {
// 获取加密器
StringEncryptor stringEncryptor = JasyptUtil.getInstance(password);
// 加密
String encrypt = stringEncryptor.encrypt(ENCRYPT_PASS);
System.out.println("【" + ENCRYPT_PASS + "】被加密成【" + encrypt + "】");
// 解密
String decrypt = stringEncryptor.decrypt(DECRYPT_PASS);
System.out.println("【" + DECRYPT_PASS + "】被解密成【" + decrypt + "】");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取加密器
*/
public static StringEncryptor getInstance(String password) throws Exception {
if (password == null || password.trim().isEmpty()) {
System.out.println("秘钥不能为空!");
throw new Exception("org.jasypt.encryption.StringEncryptor秘钥不能为空!");
}
if (stringEncryptor == null) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
//加盐
config.setPassword(password);
//默认的算法: PBEWITHHMACSHA512ANDAES_256
config.setAlgorithm(algorithm);
//默认的迭代次数: 1000
config.setKeyObtentionIterations("1000");
//默认的线程池大小: 1
config.setPoolSize("1");
//默认的提供者: SunJCE
config.setProviderName("SunJCE");
//默认的盐生成器:org.jasypt.salt.RandomSaltGenerator
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
//默认的iv生成器:org.jasypt.iv.RandomIvGenerator
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
//默认的输出类型:base64
config.setStringOutputType("base64");
encryptor.setConfig(config);
stringEncryptor = encryptor;
}
return stringEncryptor;
}
}
4.运行后结果
5.加密后数据库配置
# NAS 数据库
url: jdbc:mysql://192.168.1.1:3306/mysql?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC
username: root
password: ENC@[加密后的密码]
生产环境安全处理
jasypt的password值放在配置文件中在生产环境中是不安全的,我们可以将password值放到启动命令中,删除配置文件中password 的配置行
java -jar xxx.jar --jasypt.encryptor.password=xxx
# 或者
java -Djasypt.encryptor.password=xxx -jar xxx.jar
知识点
Jasypt 提供了不同强度的文本 (String)加密接口,根据强度排序依次为
- BasicTextEncryptor(PBEWithMD 5 AndDES)
- StrongTextEncryptor (PBEWithMD 5 AndTripeDES)
- AES 256 TextEncryptor (PBEWithHMACSHA 512 AndAES_256)