一、前言
之前我写过一篇文章使用SM4国密加密算法对Spring Boot项目数据库连接信息以及yaml文件配置属性进行加密配置(读取时自动解密),对Spring Boot项目的属性读取时进行加解密,但是没有说明对System.setProperty(key, value)设置的属性进行读取加解密,这个在开发过程中应该怎么实现呢?
二、开发方案
前置步骤我们在这里不再描述了,可以参考使用SM4国密加密算法对Spring Boot项目数据库连接信息以及yaml文件配置属性进行加密配置(读取时自动解密),我们这里参考一下解决方案。
1. 通过扩展EnvironmentPostProcessor接口进行参数解密
1.1 示例代码
import com.learn.SM4Utils; // 自己实现的SM4算法工具类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyEnv implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 获取所有系统参数
Properties properties = System.getProperties();
// 遍历
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
// 获取设置值
Object value = entry.getValue();
if (value != null) {
String v = (String) value;
if (v.startsWith(SM4Utils.SM4_PREFIX)) { // 判断是否进行了加密配置
// 进行解密,然后重新设置
System.setProperty((String) entry.getKey(), SM4Utils.decryptStr(v));
}
}
}
}
}
1.2 注册自定义EnvironmentPostProcessor处理器
在resource目录下新建META-INF目录,新建spring.factories文件
,添加如下内容:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.learn.env.MyEnv
1.3 测试
示例代码:
SpringBootApplication
public class JenkinsDemo01Application {
public static void main(String[] args) {
String s = SM4Utils.encryptStr("hello,CSDN!");
System.out.println("设置的value:" + s);
System.setProperty("testKey", s);
SpringApplication.run(JenkinsDemo01Application.class, args);
System.out.println("获取的value:" + System.getProperty("testKey"));
}
}
测试结果:
)
2. 通过实现ApplicationListener事件监听实现
2.1 示例代码
import com.learn.SM4Utils;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
// 获取所有系统参数
Properties properties = System.getProperties();
// 遍历
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
// 获取设置值
Object value = entry.getValue();
if (value != null) {
String v = (String) value;
if (v.startsWith(SM4Utils.SM4_PREFIX)) { // 判断是否进行了加密配置
// 进行解密,然后重新设置
System.setProperty((String) entry.getKey(), SM4Utils.decryptStr(v));
}
}
}
}
}
1.2 注册自定义ApplicationListener事件监听
在resource目录下新建META-INF目录,新建spring.factories文件
,添加如下内容:
org.springframework.context.ApplicationListener=\
com.learn.event.MyEventListener
1.3 测试
示例代码:
SpringBootApplication
public class JenkinsDemo01Application {
public static void main(String[] args) {
String s = SM4Utils.encryptStr("hello,CSDN!");
System.out.println("设置的value:" + s);
System.setProperty("testKey", s);
SpringApplication.run(JenkinsDemo01Application.class, args);
System.out.println("获取的value:" + System.getProperty("testKey"));
}
}
测试结果:
通过以上两种方式,可以在项目启动过程中获取设置System参数,进行解密,这样获取的时候就是解密以后的参数了。