1.为什么要有这个需求?
一般当我们自己练习的时候,username和password直接是爆露出来的
假如别人路过你旁边时看到了你的数据库账号密码,他跑到他的电脑打开navicat直接就是一顿连接,直接疯狂删除你的数据库,那可就废了,所以像这种重要的敏感信息,一般是加密过后显示出来的,也就是数据的脱敏,一般公司你看到的数据库连接信息是这样的。
这显然就是加密过后的,但是数据库连接时如果获取到的是你加密过后的密码,那肯定是错误的,所以我们需要在数据库获取到信息之前,把它给解密,切记解密是在获取到数据之前进行的。
2.jasypt是如何保证数据安全的?
可能你会好奇,它既然能解密,那我拿着你的密文去调用jasypt提供的解密方法(api)去解密不就行了吗?但是jasypt可不是这么干的!它提供了一个盐salt,它加密和解密是如下过程进行的。
可以看出没有盐你就算知道密文也没用。也可以说盐就是打开你金库的钥匙。此时你可能会好奇,那密文肯定是代码里面生成的啊,那你生成的时候盐salt和原密码肯定也是写在代码里了,那不也不安全吗?其实这个密文是我们提前通过测试工具类生成好的再放到配置文件中,生成好以后测试工具类就可以直接删除了,所以盐和原密码不会暴漏在代码中,最终只有你知道。
3.SpringBoot项目中如何使用jasypt
3.1引入依赖
<!--jasypt-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
3.2创建jasypt工具类
主要用于提前进行加密和解密的
package com.fzy.utils;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
public class JasyptPasswordUtil {
private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";
/**
* 加密
* @param salt 你设置加密用的盐
* @return 加密类PooledPBEStringEncryptor所需要的配置类
*/
public static SimpleStringPBEConfig getJasyptConfig(String salt){
//加解密配置
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(salt);//配置盐!!!极其重要
config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);//加密算法
//下面的配置不用关心
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
return config;
}
/**
* 加密方法
* @param salt 输入盐
* @param text 输入需要加密的文本
* @return 密文
*/
public static String encryptText(String salt, String text){
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();//加密类
SimpleStringPBEConfig config = getJasyptConfig(salt);//获取并设置加密配置类
encryptor.setConfig(config);
String encryptText = encryptor.encrypt(text);//进行加密
return encryptText;
}
/**
* 解密方法,此处没什么用,就是用来自己看看能不能解密
* @param salt 输入盐
* @param text 输入需要加密的文本
* @return 明文
*/
public static String decryptText(String salt, String text){
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = getJasyptConfig(salt);
encryptor.setConfig(config);
String decryptText = encryptor.decrypt(text);
return decryptText;
}
public static void main(String[] args) {
//生成的密文将来放到你yml文件中,例如数据库的用户名密码等敏感信息
String encryptText = encryptText("biecaile", "root");
System.out.println("加密后:" + encryptText);
String decrypt = decryptText("biecaile", encryptText);
System.out.println("解密后:" + decrypt);
}
}
运行后的结果:
稍微了解两个加密算法,PBEWithMD5AndDES和PBEWITHHMACSHA512ANDAES_256
这两个算法跟jasypt的版本有关,如果我们不配置加密算法,无论是3.0还是2.0好像加密都是PBEWithMD5AndDES,但是解密,如果2.0.xxx是使用的PBEWithMD5AndDES,3.0使用的是PBEWITHHMACSHA512ANDAES_256,此处不是指我们自己测试去解密,而是指再配置完yml文件或者程序参数后自己去解密(下面),所以如果解密算法与加密不一致就会报错(一般启动项目就会报错),最好指定加密算法,像我是3.0版指定加密算法为PBEWITHHMACSHA512ANDAES_256
那在yml文件中就不用再配置解密算法了。配一下当然最好。
3.3配置yml文件
jasypt:
encryptor:
password: biecaile #解密盐值
algorithm: PBEWITHHMACSHA512ANDAES_256 #解密算法
test:
password: ENC(MsGb7KJD6ZxdEH5O42MM+lDVH6mvtP46IlwVqbXq/CHQR75x2+WG7YyOf3Ootndd)
其中的test:password是我们自定义的,主要用于测试,ENC()这个是jasypt自动识别yml属性值的一个标识,只要加上,当前值就会被解析成明文,里面存放的是我们生成的密文。
3.4编写读取yml文件属性值的配置类TestConfig
这里主要是为了测试能不能在获取到属性之前,密文已经被解密了,也就是说此处如果正确的话,获取到的就是我们的明文“root”,实际工作根本不需要
package com.fzy.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
public class TestConfig {
@Value("${test.password}")
private String password;
}
3.5随便编写一个TestController去测试获取该数据
@Controller
@RequestMapping("/test")
public class TestController {
@Autowired
private TestConfig testConfig;
@RequestMapping("/getText")
@ResponseBody
public String getText(){
return testConfig.getPassword();
}
}
结果发现获取到的是明文,已经成功了
4.能在配置文件中配盐值salt吗?
肯定是不行的,这样salt直接就爆露出来了,很危险,尤其是放在代码中,也很容易就发现,一般不会写在配置文件中的,我们可以把它放到启动类的程序实参中
填写:--jasypt.encryptor.password=你的盐值salt,然后apply+ok确定就行。
配置完以后把你在配置文件中的password(所谓的salt去掉就行),结果一样的。一般只要salt配的不对,程序启动就会直接报错。
总结:这样的话,就算我把代码给你,你都跑不起来项目,因为你没有salt就配不了,然后你只能去问我要,我就不给你,那么你就破解不了数据库的密文,你就别想连上我的数据库。