一、 Spring方式
spring对配置文件中已加密属性进行解密
spring中可以使用PropertyPlaceholderConfigurer对properties文件中的属性进行解密。
1. 在xml文件中配置需要解密的属性及所在文件
<bean class="com.test.util.EncryptPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
<property name="encryptedProps">
<set>
<value>jdbc.password</value>
</set>
</property>
</bean>
2. 创建EncryptPropertyPlaceholderConfigurer类
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Logger logger = LogManager.getLogger(getClass());
//密钥
private final static String SECRETKEY = "test";
//向量
private final static String IV = "test01";
//加密属性名单
private Set<String> encryptedProps = Collections.emptySet();
public void setEncryptedProps(Set<String> encryptedProps) {
this.encryptedProps = encryptedProps;
}
@Override
protected String convertProperty(String propertyName, String propertyValue){
if (encryptedProps.contains(propertyName)){
String decryptValue = null;
try {
//自己相应的解密方法
decryptValue = DESUtil.decryptStringURLDecoder(SECRETKEY, IV, propertyValue);
} catch (Exception e) {
e.printStackTrace();
}
logger.debug("属性{}已解密:{}", propertyName, decryptValue);
if(null != decryptValue){
return super.convertProperty(propertyName, decryptValue);
}
}
return super.convertProperty(propertyName, propertyValue);
}
}
spring 方式的缺陷:
- 1、目前只支持properties配置文件,当我们使用yaml文件后就不生效了,运行会报文件格式异常,如果要生效,必须复写底层的loadProperties方法分别对不同格式的文件进行解析。但是这样可能会麻烦的多。
- 2、当我们使用spring boot后,对数据库相关配置参数解析后,数据库自动初始化装配无法成功,即数据库会在PropertyPlaceholderConfigurer类之前初始化,如果加密内容是数据库连接密码,那么程序启动后会因为数据库无法连接而报错,程序自动挂断。
SpringBoot方式
使用jasypt-spring-boot
1. 介绍
jasypt-spring-boot
jasypt可以在springboot注入property和yml配置文件中的值之前,将配置文件中的值先预先处理的工具。可以用来实现对数据库账号密码等敏感信息密文解密的功能。
2. Maven依赖
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
3. 注册解密Bean
public class EncryptionPropertyConfig {
@Bean(name = "encryptablePropertyResolver")
public EncryptablePropertyResolver encryptablePropertyResolver() {
return new EncryptionPropertyResolver();
}
class EncryptionPropertyResolver implements EncryptablePropertyResolver {
private Logger logger = LogManager.getLogger(getClass());
//密钥
private final static String SECRETKEY = "test";
//向量
private final static String IV = "test01";
@Override
public String resolvePropertyValue(String s) {
//已DES@开头的属性
if (s.startsWith("DES@")) {
String propertyValue = s.substring(4);
try {
logger.info("解密前密码:{}", propertyValue);
//自定义的解密方法
String password = DESUtil.decryptStringURLDecoder(SECRETKEY, IV, propertyValue);
logger.info("解密后密码:{}", password);
return password;
} catch (Exception e) {
e.printStackTrace();
}
}
return s;
}
}
}
4. 配置文件
application.yml文件
spring:
datasource:
druid:
username: desc
password: DES@5g3%2Dd8fQr7Ws7kCs%2FFT3Jg%3D%3D
5. 测试(转)
5.1、 property配置文件
# 127.0.0.1的密文为e3zcSlYS29N0Y3i+mVdkgQ==
datasource.host=DES@e3zcSlYS29N0Y3i+mVdkgQ==
# 3306的密文为S6mBLsaSBEw=
datasource.port=DES@S6mBLsaSBEw=
datasource.database=test
datasource.url=jdbc:mysql://${datasource.host}:${datasource.port}/${datasource.database}?useUnicode=true&characterEncoding=utf8
5.2、注入
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ApplicationTests {
@Value("${datasource.url}")
private String url;
@Test
public void testJasypt() {
System.out.println(url);
}
}
5.3、 输出
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8