在日常开发中连接数据库是必然的,开发和测试环境数据库使用敏文密码还好,生产如果采用明文配置讲会有安全问题,jasypt是一个通用的加解密库,我们可以使用他来进行对数据库的加密操作。
第一种方式
一下这种方式只针对于使用Druid连接池的项目。
pom
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
Main
public static void main(String[] args) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
// 加密所需的salt(盐)
textEncryptor.setPassword("");
// 要加密的数据(数据库的用户名或密码)
String password = textEncryptor.encrypt("");
System.out.println("password:" + password);
}
运行以后把加密之后的密码放入yml配置文件中。
修改数据源
加密需要使用到盐值,所以我们这里配置通过启动参数来进行传递。
自定义类-SyncDataSource
SyncDataSource继承com.alibaba.druid.pool.DruidDataSource重写getPassword方法。
public class SyncDataSource extends DruidDataSource {
private static String key = "";
public SyncDataSource() {
}
/**
* 如果有多个数据库可以传递一个type类型来区分盐值
*
* @param publicKey
*/
public SyncDataSource(String publicKey) {
key = publicKey;
}
@Override
public String getPassword() {
// 获取密码
String encPassword = super.getPassword();
// 解密密码
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(key);
String decrypt = textEncryptor.decrypt(encPassword);
return decrypt;
}
}
第二种方式
第一种方式可以实现数据库加密操作,但是如果项目引入了redis,阿里云oss等,用上面的方式就有一些麻烦了,这里我们就用第二种方式,在项目启动时获取yml里面的所有参数,然后进行解密操作。
pom
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
Main
public static void main(String[] args) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
// 加密所需的salt(盐)
textEncryptor.setPassword("");
// 要加密的数据(数据库的用户名或密码)
String password = textEncryptor.encrypt("");
System.out.println("password:" + password);
}
以上的步骤还是和之前的一样,只不过参数不一样了。
获取并代理配置文件-ResourcePlaceholderConfig
import com.xffjs.framework.config.properties.EncryptPropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import java.util.Properties;
/**
* @className: ResourcePlaceholderConfig
* @description: 获取配置文件
* @author: xiaofei
*/
@Configuration
public class ResourcePlaceholderConfig {
@Bean
public PropertySourcesPlaceholderConfigurer propertyConfigurer() {
PropertySourcesPlaceholderConfigurer config = new EncryptPropertyPlaceholderConfigurer();
// 获取当前所激活的配置文件
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("application.yml"));
Properties properties = yaml.getObject();
String active = properties.getProperty("spring.profiles.active");
// 读取当前所激活的配置文件
yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("application-" + active + ".yml"));
config.setProperties(yaml.getObject());
return config;
}
}
配置文件解密-EncryptPropertyPlaceholderConfigurer
import org.apache.commons.lang3.StringUtils;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import java.util.Map;
import java.util.Properties;
/**
* @className: EncryptPropertyPlaceholderConfigurer
* @description: 配置文件解密
* @author: xiaofei
* @create: 2020年12月21日
*/
public class EncryptPropertyPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer implements InitializingBean {
/**
* 需要解密的配置项前缀
*/
private static final String PREFIX_ENC = "enc:";
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
protected Properties mergeProperties() {
Properties mergedProperties = new Properties();
for (Properties localProp : localProperties) {
mergedProperties.putAll(localProp);
}
for (Map.Entry entry : mergedProperties.entrySet()) {
if (entry.getValue().toString().startsWith(PREFIX_ENC)) {
System.out.println("需要解密的key:" + entry.getValue().toString());
String key = System.getProperty("salt");
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(key);
String value = entry.getValue().toString().replace(PREFIX_ENC, StringUtils.EMPTY);
String decrypt = textEncryptor.decrypt(value);
mergedProperties.setProperty(entry.getKey().toString(), decrypt);
}
}
MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
sources.addFirst(new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergedProperties));
return mergedProperties;
}
@Override
public void afterPropertiesSet() {
localOverride = true;
}
}
盐值(salt)的配置
Idea配置:
一定要加-D,不然无法读取。
Jar启动配置:
一定放到前面,放到后面则不生效。
java -Dsalt=aaaa -jar XFBlog_prod.jar
打赏
当前共有 0 条评论