一、数据库账号密码加密
通常情况下,我们的数据库账号密码都是直接写在配置文件中的,这种写法实际是非常不安全的,当别人拿到项目配置文件之后,就能直接远程登录连接数据库,下面分析一下怎么针对数据库关键信息进行加密操作
(1)Jasypt加密库
Java库-Jasypt,全称为Java Simplified Encryption,用于加密解密。它能够让开发者用花费最小的工作而把加密集成到项目中,并且不需要对加密/解密有深入的了解。
(2)项目中配置使用Jasypt库
首先需要引用相关依赖到项目中,我这里直接以SpringBoot为例,引入依赖如下
<!-- 数据库账户加密 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
这里我没有采用最新版本,因为在使用上有一定差异
在application.yml配置文件中增加以下配置
# 数据库加密工具
jasypt:
encryptor:
password: TELLSEASALT # 盐值
创建一个普通的java main方法,用于生成加密信息
import org.jasypt.util.text.BasicTextEncryptor;
/**
* Jasypt加密库
*
* @author Tellsea
* @date 2021/02/28
*/
public class JasyptTest {
public static void main(String[] arg) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
//1.加密所需的salt(盐),配置值jasypt.encryptor.password
textEncryptor.setPassword("TELLSEASALT");
System.out.println("加密账号:" + textEncryptor.encrypt("root"));
System.out.println("加密密码:" + textEncryptor.encrypt("123456"));
}
}
直接结果如下,生成加密后的信息
加密账号:DIeS/Bxlt7WmSnxNyC27gg==
加密密码:mcwxAAsJ8Ii62wxk5GegjA==
然后将加密后的信息填写在需要替换的明文处,默认使用 ENC() 包括加密字符串
# mysql
spring:
datasource:
druid:
username: ENC(2WKbOhyeCzhiLVq4E9KUnA==)
password: ENC(6QcZNCQYmtdynSKxxwagOw==)
加密字符串的前缀后缀可以自行配置
# 数据库加密工具
jasypt:
encryptor:
property:
prefix: AAA( # 配置前缀
suffix: )BBB # 配置后缀
常用其他配置,统一配置前缀为jasypt.encryptor,相关配置的详细信息可以在源码的JasyptEncryptorConfigurationProperties类中查看,由于版本的不同,需要注意一下可能默认值会不同
配置项 | 必须 | Default Value |
---|---|---|
jasypt.encryptor.password | True | - |
jasypt.encryptor.algorithm | False | PBEWithMD5AndDES |
jasypt.encryptor.keyObtentionIterations | 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.iv.RandomIvGenerator |
jasypt.encryptor.stringOutputType | False | base64 |
jasypt.encryptor.proxyPropertySources | False | false |
(3)对盐值进行深度保护
综合来说解决了敏感信息加密的问题,但是伴随着一个新的问题出现,盐值是存放在application.yml配置文件中的,同样是不安全的,可以说是没有彻底解决加密问题,下面我们继续修改配置解决这个问题
先我们删除application.yml配置文件中jasypt.encryptor
属性
下面有三种方式来解决这个问题(推荐第三种):
- 第一种:JVM参数
在启动项目时,增加参数:-Djasypt.encryptor.password=TELLSEASALT
- 第二种:服务器的环境变量
第二种,将盐值配置成服务器的系统环境变量,启动时获取参数,只有拿到服务器权限的人,才能查看到盐值在哪
# 新增变量
export JASYPT_PASSWORD = TELLSEASALT
# 使配置文件生效
source /etc/profile
# 启动项目时,增加启动参数配置
java -jar -Djasypt.encryptor.password=${JASYPT_PASSWORD} xxx.jar
- 第三种:使用自定义的Encryptor来存放
增加一个自定义配置类
import org.jasypt.encryption.StringEncryptor;
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;
/**
* 加密配置
*
* @author Tellsea
* @date 2021/03/01
*/
@Configuration
public class EncryptorConfig {
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("TELLSEASALT");
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.salt.NoOpIVGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
到此,数据库账号密码加密已经完成!