背景
最近开展的项目,审查方要求配置文件不得出现敏感信息的明文信息,比如数据库密码就是敏感信息。由于需要审查的项目都是基于Spring框架实现的业务需求。传统的SpringWeb项目 与 SpringBoot 项目。所以接下来介绍这两种项目的如何实现加密方案。
SrpingWeb 项目
基于Spring项目,我们的项目加载配置文件时是如下方式:
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
其实读取配置文件的实现类是均是 PropertyPlaceholderConfigurer 如果想对配置文件的读取值做处理,可以继承 PropertyPlaceholderConfigurer 类并覆写 convertProperties 方法。
public class ConvertPwdPropertyConfigurer extends PropertyPlaceholderConfigurer{
@Override
protected String convertProperty(String propertyName, String propertyValue) {
//所有值开头以 encrypt: 开始的,则进行解密
if(propertyValue.contains("encrypt:")){
try {
//解密工具类
return DecryptConfigUtil.getDecryptShareString(propertyValue, false);
} catch (Exception e) {
e.printStackTrace();
}
}
//无需解密
return propertyValue;
}
}
并且把上述配置更改为如下即可:
<bean
class="xxx.config.ConvertPwdPropertyConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
具体的加解密方案自己定即可。
SpringBoot 项目
对于此框架的配置加密实现,是依赖于 jasypt 的。
pom 依赖
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
注入 EncryptablePropertyResolver
注入一个默认约定名称的 bean ,此实例需继承 EncryptablePropertyResolver
@Configuration
@Slf4j
public class EncryptionPropertyConfig {
@Bean(name="encryptablePropertyResolver")
public EncryptablePropertyResolver encryptablePropertyResolver() {
return new EncryptionPropertyResolver();
}
}
EncryptionPropertyResolver 实现:
public class EncryptionPropertyResolver implements EncryptablePropertyResolver {
@Override
public String resolvePropertyValue(String value) {
if(StringUtils.isBlank(value)) {
return value;
}
if(value.startsWith("encrypt:")) {
log.debug("密文信息配置"+value);
return resolveDESValue(value);
}
// 不需要解密的值直接返回
log.debug("明文信息配置"+value);
return value;
}
//解密实现
private String resolveDESValue(String value) {
String decryptShareString ="";
try{
decryptShareString = DecryptConfigUtil.getDecryptShareString(value, true);
}catch (Exception e){
e.printStackTrace();
}
return decryptShareString;
}
}
结束语
综上是基于Spring框架两种情况的配置文件 加密预处理实现。具体如何实现加密解密逻辑需自己定义,建议:可以使用RSA公钥加密私钥解密的方案,公钥公开出去对需加密的内容进行加密,私钥写进代码里,启动时进行如上操作的解密。(私钥如何管理不做过多探讨)
update
好多项目都以来的Druid连接池,有些情况对数据库密码的加密依赖于Druid的实现。我是不推荐的,其实质时使用随机生成的私钥对密码进行加密,然后使用公钥解密,公钥于密文信息配置到配置文件中,也就意味着对方拿到配置文件也就可以对密文进行解密,所以不知意义何在。
参考:https://yq.aliyun.com/articles/182720