【开源项目】SpringBoot之Jasypt实现配置文件加密解密

需求背景

数据库密码直接明文写在配置中,对安全来说,是一个很大的挑战。一旦密码泄漏,将会带来很大的安全隐患。尤其在一些企业对安全性要求很高,因此我们就考虑如何对密码进行加密。

快速入门

引入Maven

        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>3.0.4</version>
        </dependency>

配置文件

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    # jasypt加密的盐值
    password: 123456
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

spring:
  # 数据库配置
  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ENC(W+vcCn52uIhTRfwf++D3H1BSjwgAfUvmgzC4ksV5hqjRQrXpFzL5tNKzf6Tpj42kTrlycDr5//wi4jmb+wKrqZGCH2vrcRluP92CH827bJK66qnoUUXVp4UlvC/qYaOFvI/UNWIQUX3SlIUBi5eNA/qS8YWQAxcoBbMQ3qRWTa85il2Ue0vjhF4X7VlNF9LkXXbz9GYhU0g=)
    username: ENC(zJI0GE9ZpOJjuaRjk2B9uA==)
    password: ENC(a/kikxloS7NP34jJLgu3ng==)

解密

@RestController
public class TestController {

    @Value("${spring.datasource.url}")
    private String dsUrl;

    @GetMapping("/test")
    public String getData() {
        System.out.println(dsUrl);
        return dsUrl;
    }
}

源码解析

  • jaspcry-spring-boot-starter的jar包中找到自动装配的入口:spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringBootAutoConfiguration

org.springframework.cloud.bootstrap.BootstrapConfiguration=com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringCloudBootstrapConfiguration

JasyptSpringBootAutoConfiguration加载配置类EnableEncryptablePropertiesConfiguration

@Configuration
@Import({EnableEncryptablePropertiesConfiguration.class})
public class JasyptSpringBootAutoConfiguration {
    public JasyptSpringBootAutoConfiguration() {
    }
}

EnableEncryptablePropertiesConfiguration加载bean工厂后置处理类,EnableEncryptablePropertiesBeanFactoryPostProcessor

@Configuration
@Import({EncryptablePropertyResolverConfiguration.class, CachingConfiguration.class})
@Slf4j
public class EnableEncryptablePropertiesConfiguration {

    @Bean
    public static EnableEncryptablePropertiesBeanFactoryPostProcessor enableEncryptablePropertySourcesPostProcessor(final ConfigurableEnvironment environment, EncryptablePropertySourceConverter converter) {
        return new EnableEncryptablePropertiesBeanFactoryPostProcessor(environment, converter);
    }
}

EnableEncryptablePropertiesBeanFactoryPostProcessor#postProcessBeanFactory,主要是将所有的PropertySource都转换成了EncryptablePropertySource

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.info("Post-processing PropertySource instances");
        MutablePropertySources propSources = environment.getPropertySources();
        converter.convertPropertySources(propSources);
    }

重写了获取配置信息的接口,EncryptablePropertySource#getProperty()

    default Object getProperty(EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter, PropertySource<T> source, String name) {
        Object value = source.getProperty(name);
        if (value != null && filter.shouldInclude(source, name) && value instanceof String) {
            String stringValue = String.valueOf(value);
            return resolver.resolvePropertyValue(stringValue);
        }
        return value;
    }

DefaultPropertyResolver#resolvePropertyValue,判断是否加密了,如果加密进行解密操作。

    public String resolvePropertyValue(String value) {
        return Optional.ofNullable(value)
                .map(environment::resolvePlaceholders)
                .filter(detector::isEncrypted)
                .map(resolvedValue -> {
                    try {
                        String unwrappedProperty = detector.unwrapEncryptedValue(resolvedValue.trim());
                        String resolvedProperty = environment.resolvePlaceholders(unwrappedProperty);
                        return encryptor.decrypt(resolvedProperty);
                    } catch (EncryptionOperationNotPossibleException e) {
                        throw new DecryptionException("Unable to decrypt property: " + value + " resolved to: " + resolvedValue + ". Decryption of Properties failed,  make sure encryption/decryption " +
                                "passwords match", e);
                    }
                })
                .orElse(value);
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值