Springboot 自定义配置文件加密规则

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 一般情况下,我们做项目的时候,中间件例如mysql,redis, zk 的账号密码一般都是写在配置文件里面的, 这样代码泄露的情况下, 就很不安全。

一般情况下,我们做项目的时候,中间件例如mysql,redis, zk 的账号密码一般都是写在配置文件里面的, 这样代码泄露的情况下, 就很不安全。

由第三方的加密的工具 jasypt 这种jar包。 这里我们仿写它来实现自己的配置文件加密规则。

jasypt 连接:https://github.com/ulisesbocchio/jasypt-spring-boot

具体的使用大家看我发的地址。

这里我们要用到ConfigurableEnviroment 这个类,我们来看一下源码

public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {

void setActiveProfiles(String... var1);

void addActiveProfile(String var1);

void setDefaultProfiles(String... var1);

// resource 文件多个,这个可以是classpath ,file ,default 的

MutablePropertySources getPropertySources();

// 获取系统配置文件

Map<String, Object> getSystemProperties();

// 获取系统环境变量

Map<String, Object> getSystemEnvironment();

void merge(ConfigurableEnvironment var1);

}

首先我们要自己写一个类实现BeanFactoryPostProcessor ,和order 接口

public class PropertiesEncryptionConfig implements BeanFactoryPostProcessor, Ordered {

// 前缀的key 
public static final String PREFIX_PROPERTY = "xxxxx.encrypt.prefix";
// 后缀的key 
public static final String SUFFIX_PROPERTY = "xxxxx.encrypt.suffix";

// 私钥的key 
public static final String RSA_PRIVATE_KEY_PROPERTY = "xxxxx.encrypt.privateKey";

// 前缀默认值
public static final String DEFAULT_PREFIX = "xxxxx[";

 //后缀默认值
public static final String DEFAULT_SUFFIX = "]";


private static final Logger LOG = LoggerFactory.getLogger(PropertiesEncryptionConfig.class);

// 在通过@bean 注入进来
public   ConfigurableEnvironment  environment ;

public PropertiesEncryptionConfig(ConfigurableEnvironment environment) {
    this.environment = environment;
}

private String prefix;

private String suffix;

private String privateKey;


@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    MutablePropertySources propertySources = environment.getPropertySources();
    for (PropertySource<?> propertySource : propertySources) {
        if (propertySource instanceof OriginTrackedMapPropertySource) {
            // 只有这个才是加载properties 文件的,getsource 返回的就是map
            OriginTrackedMapPropertySource om = (OriginTrackedMapPropertySource) propertySource;
            Map<String, Object> source = om.getSource();
            source.forEach((k, v) -> {
                String property = environment.getProperty(k);
                if (hasPreAndSuf(property)) {
                    LOG.info("开始处理 k = [{}]", k);
                    try {
                        String relay = splitPreAndSuf(property, this.prefix, this.suffix);
                        // 这里获取去掉前缀后缀的值 在通过自己的解密规则 ,
                        //这里 AesUtils 可以搞成注入模式, 这样使用的时候可以进行加密。自己写aes 的加密工具类 
                        String decrypt = AesUtils.aesDecrypt(relay, getPrivateKey(environment));
                        source.put(k, decrypt);
                    }
                    catch (Exception e) {
                        LOG.error("配置文件加密异常错误信息: ", e);
                    }
                }
            });
        }
    }
}

private String getPrivateKey(ConfigurableEnvironment environment) throws Exception {
    // 支持从系统环境变量 java -jar 运行的时候获取
    this.privateKey = System.getProperty(RSA_PRIVATE_KEY_PROPERTY, "");
    if (StringUtils.hasText(this.privateKey)) {
        return this.privateKey;
    }
    // 支持从文件获取
    this.privateKey = environment.getProperty(RSA_PRIVATE_KEY_PROPERTY);
    if (StringUtils.hasText(this.privateKey)) {
        return this.privateKey;
    }
    // 都没有就会报错
    throw new Exception(" properties aes  private key is null!");
}

// 判断一下,前缀后缀是否匹配
private boolean hasPreAndSuf(String property) {
    return property.startsWith(getPrefix(environment)) && property.endsWith(getSuffix(environment));
}

// 去掉前缀后缀获取中间值
protected String splitPreAndSuf(String str, String prefix, String suffix) {
    return str.replace(prefix, "").replace(suffix, "");
}

// 获取后缀,没有使用默认值
private String getSuffix(ConfigurableEnvironment environment) {
    this.suffix = environment.getProperty(SUFFIX_PROPERTY);
    if (StringUtils.hasLength(suffix)) {
        return this.suffix;
    }
    this.suffix = DEFAULT_SUFFIX;
    return DEFAULT_SUFFIX;
}

// 获取前缀,使用默认值

private String getPrefix(ConfigurableEnvironment environment) {
    this.prefix = environment.getProperty(PREFIX_PROPERTY);
    if (StringUtils.hasLength(prefix)) {
        return this.prefix;
    }
    this.prefix = DEFAULT_PREFIX;
    return DEFAULT_PREFIX;
}

/**
 *  提高优先级
 * @return
 */
@Override
public int getOrder() {
    return Ordered.LOWEST_PRECEDENCE -100;
}

}

@Configuration
public class EnablePropertiesEncryption {

@Bean
public PropertiesEncryptionConfig getPropertiesEncryption(ConfigurableEnvironment configurableEnvironment){
    return  new PropertiesEncryptionConfig(configurableEnvironment);
}

// 加密解密工具类 ,可以在spring单元测试使用@Autowired注入
@Bean
public AesUtils getAes(){
    return  new AesUtils();
}

}

这样我们就基本实现了jasypt 的功能。

相关文章
|
5月前
|
安全 Java 数据安全/隐私保护
Spring Boot中的数据加密与解密
Spring Boot中的数据加密与解密
|
2月前
|
存储 安全 Java
|
2月前
|
存储 算法 安全
SpringBoot 接口加密解密实现
【10月更文挑战第18天】
|
2月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
36 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
1月前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
20 0
|
3月前
|
消息中间件 NoSQL 安全
(转)Spring Boot加载 不同位置的 application.properties配置文件顺序规则
这篇文章介绍了Spring Boot加载配置文件的顺序规则,包括不同位置的application.properties文件的加载优先级,以及如何通过命令行参数或环境变量来指定配置文件的名称和位置。
|
4月前
|
jenkins 应用服务中间件 持续交付
如何配置 Nginx 作为 Jenkins 的反向代理并启用 SSL 加密
如何配置 Nginx 作为 Jenkins 的反向代理并启用 SSL 加密
235 8
|
4月前
|
安全 Java Shell
"SpringBoot防窥秘籍大公开!ProGuard混淆+xjar加密,让你的代码穿上隐形斗篷,黑客也无奈!"
【8月更文挑战第11天】开发SpringBoot应用时,保护代码免遭反编译至关重要。本文介绍如何运用ProGuard和xjar强化安全性。ProGuard能混淆代码,去除未使用的部分,压缩字节码,使反编译困难。需配置ProGuard规则文件并处理jar包。xjar则进一步加密jar包内容,即使被解压也无法直接读取。结合使用这两种工具可显著提高代码安全性,有效保护商业机密及知识产权。
378 3
|
4月前
|
JSON 算法 API
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
|
4月前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
381 0