SpringBoot配置文件内容加密,实现敏感信息保护 - 第431篇

SpringBoot配置文件内容加密,实现敏感信息保护 - 第431篇


历史文章(累计400+篇文章)

国内最全的Spring Boot系列之一

国内最全的Spring Boot系列之二

国内最全的Spring Boot系列之三

国内最全的Spring Boot系列之四

国内最全的Spring Boot系列之

SpringBoot使用thymeleaf实现布局方案二,方案在手说走就走 - 第425篇

SpringBoot/Spring扩展点系列之初出茅庐ApplicationContextInitializer - 第426篇

SpringBoot/Spring扩展点BeanDefinitionRegistryPostProcessor - 第427篇

SpringBoot/Spring扩展点系列之叱咤风云BeanFactoryPostProcessor - 第428篇

SpringBoot扩展点系列之InstantiationAwareBeanPostProcessor模拟AOP - 第429篇一款利用人工智能生成模型来合成代码的工具Copilot - 第430篇


悟纤:师傅,师傅,你在哪里?



师傅:为师睡午觉刚醒呐。




悟纤:师傅,你说你在那里享福呢,徒儿都要愁死了。




师傅:徒儿,这是怎么了,闹得哪出呢?

​悟纤:师傅,我觉得配置文件的重要配置,明文显示不是很安全呐,有没有办法,加密显示呐。

师傅:那是肯定的有的。今天咱们就一起来瞅一瞅这配置加密,以此来实现敏感信息的保护。

悟纤:那师傅,赶紧的呗~ 我已经迫不及待了。




导读

我们的配置文件中,其实包含着大量与安全相关的敏感信息,比如:数据库的账号密码、一些服务的密钥等。这些信息一旦泄露,对于企业的重要数据资产,那是相当危险的。所以,对于这些配置文件中存在的敏感信息进行加密,是每个成熟开发团队都一定会去的事。

一、配置信息加密方案

在前面的章节中,我们有学习过Spring的扩展点,如果把扩展点搞明白的话,就可以来实现一套加密解密的方案了;另外既然我们能想到要对配置文件的重要信息加密,那么这个技术方案一定是就存在了,所以可以找找成熟的方案直接使用,总结一下:

(1)方案一:借助Spring的扩展点自我进行实现加密解密。

(2)方案二:使用第三方框架来实现加密解密(实际上第三方框架底层的实现,也是借助了Spring的扩展点)。

二、jasypt

这一节,我们就先来看看第三方框架jasypt如何来进行加密解密。

2.1 jasypt是什么?

Jasypt的github地址:

github.com/jasypt/jasyp

看官网的介绍:Jasypt (Java Simplified Encryption) 是一个 java 库,它允许开发人员以最小的努力将基本的加密功能添加到他/她的项目中,而无需深入了解密码学的工作原理。

2.2 Jasypt要怎么用?

核心步骤,就两个:

(1)添加jasypt依赖

(2)配置文件添加配置

2.3 Jasypt实战

2.3.1 构建SpringBoot项目

构建一个SpringBoot项目,取名为:spring-boot-jasypt-example。

项目名,取啥不重要,你高兴就行。

2.3.2 添加依赖包

在pom.xml文件,添加jasypt的starter:

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

还有一个就是插件:

<plugin>
   <groupId>com.github.ulisesbocchio</groupId>
   <artifactId>jasypt-maven-plugin</artifactId>
   <version>3.0.4</version>
</plugin>

插件是非必须的,本节讲解需要用到,所以先引入。

总的pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.7.0</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.kfit</groupId>
   <artifactId>spring-boot-jasypt-example</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>spring-boot-jasypt-example</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
​
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
​
      <dependency>
         <groupId>com.github.ulisesbocchio</groupId>
         <artifactId>jasypt-spring-boot-starter</artifactId>
         <version>3.0.4</version>
      </dependency>
​
   </dependencies>
​
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
​
         <plugin>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-maven-plugin</artifactId>
            <version>3.0.4</version>
         </plugin>
​
      </plugins>
   </build>
​
</project>


2.3.3 添加配置信息

在application.properties添加配置:

# 配置加密时使用的密码/加密的盐
jasypt.encryptor.password=wuqian
​
# 例子用的密码
datasource.password = 123456
redis.password = 123456


jasypt.encryptor.password这个配置很重要,可以理解是加密的密码/加密的盐。

实际中,这个直接配置在配置文件,是否合理?大家可以思考一下,我们想接着往下讲解。

2.3.4 配置加密

可以发现,现在配置文件的密码还是明文呢?那么我们如何实现加密呢?

(1)方案1:命令行方式,使用java命令运行jar

找到jasypt-x.x..jar运行如下命令:

java -cp  jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123456" password=wuqian algorithm=PBEWithMD5AndDES

input :明文密码

password:要加的盐(可自己设置)

algorithm:加密算法,这里使用 PBEWithMD5AndDES

结果如下,OUTPUT就是加密之后的密文(密码)



将加密的密文,替换掉配置文件的内容即可。


(2)方案2:代码方式

package com.kfit;
​
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
​
import javax.annotation.PostConstruct;
​
/**
 *
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2022-06-20
 * @slogan 大道至简 悟在天成
 */
@RestController
public class DemoController {
​
    @Value("${datasource.password}")
    private String dataSourcePwd;
​
    @Value("${redis.password}")
    private String redisPwd;
​
    @PostConstruct
    public void init(){
        System.out.println("dataSourcePwd:"+dataSourcePwd+",redisPwd:"+redisPwd);
    }
​
}

(3)方案3:插件的插件

如果使用插件的方式,就需要添加插件jasypt-maven-plugin(已经在前面配置的时候,一起添加了);如果不是使用这种方式的话,这个插件就可以不用添加。

首先,修改要加密的内容,用DEC()将待加密内容包裹起来,比如:

datasource.password = DEC(123456)


这个的作用,就是jasypt插件,才能知道要加密那些配置文件的内容。

紧接着使用使用jasypt-maven-plugin插件来给DEC()包裹的内容实现批量加密。

在终端中执行下面的命令:

mvn jasypt:encrypt -Djasypt.encryptor.password=wuqian

注意:这里-Djasypt.encryptor.password参数必须与配置文件中的一致,不然后面会解密失败。

执行之后,重新查看配置文件,可以看到,自动变成了:



其中,ENC()跟DEC()一样都是jasypt提供的标识,分别用来标识括号内的是加密后的内容和待加密的内容。

如果当前配置文件已经都是ENC()内容了,那么我们可以通过下面的命令来解密配置文件,查看原始信息:



特别说明:该操作不会修改配置文件,只会在控制台输出解密结果。

2.3.5 测试类

写个测试类,看看在代码中,是否可以获取到原文?

package com.kfit;
​
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
​
import javax.annotation.PostConstruct;
​
/**
 *
 *
 * @author 悟纤「公众号SpringBoot」
 * @date 2022-06-20
 * @slogan 大道至简 悟在天成
 */
@RestController
public class DemoController {
​
    @Value("${datasource.password}")
    private String dataSourcePwd;
​
    @Value("${redis.password}")
    private String redisPwd;
​
    @PostConstruct
    public void init(){
        System.out.println("dataSourcePwd:"+dataSourcePwd+",redisPwd:"+redisPwd);
    }
​
}

执行测试,查看下结果:




三、加密盐安全问题

之前是把盐值存储在配置文件实际上是否加密都成了问题了,那么这个怎么办呢?

很简单盐值应该放在系统属性、命令行或是环境变量来使用。

(1)自定义加密前后缀,让加密更安全。

默认是ENC,jasypt.encryptor.property.prefix配置来重新定义。

(2)使用自定义加密器。

使用的是默认的加密规则,这一点会让当自定义加密密钥泄漏时可能变得不安全。为此我们可以自定义加密规则。

(3)加密密钥不要写在配置文件中

方式一:直接作为程序启动时的命令行参数来带入

java -jar xxx.jar --jasypt.encryptor.password=wuqian

方式二:直接作为程序启动时的应用环境变量来带入

java -Djasypt.encryptor.password=wuqian -jar xxx.jar

方式三:甚至可以作为系统环境变量的方式来带入

比方说,我们提前设置好系统环境变量JASYPT_ENCRYPTOR_PASSWORD = wuqian,则直接在Spring Boot的项目配置文件中做如下配置即可:

jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}

总结

(1)jasypt的基本使用,添加依赖,写配置信息。

(2)jasypt的3种加密方式:命令行、代码、插件。

(3)加密盐不放在配置文件的3中方式:命令行参数、应用环境变量、系统环境变量。

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。


à悟空学院:t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:t.cn/A6ZagYTi

SpringBoot交流平台:t.cn/R3QDhU0

SpringSecurity5.0视频:t.cn/A6ZadMBe

ShardingJDBC分库分表:t.cn/A6ZarrqS

分布式事务解决方案:t.cn/A6ZaBnIr

JVM内存模型调优实战:t.cn/A6wWMVqG

Spring入门到精通:t.cn/A6bFcDh4

大话设计模式之爱你:dwz.cn/wqO0MAy7

发布于 2022-06-20 16:35