[Jasypt] to add to your configuration lock

image.png

Foreword

A few days ago, a former colleague told me Tucao, their company has a big God all the company's project code uploaded to github, and is a public project, anyone can browse. Even more frightening is the project which contains configuration files, database information, redis configuration, all in a variety of public and private key password items inside, along uploaded.

If only purely business code leak, the situation is just fine, because others know of your code, you want to do, he must make the source code read, and vulnerability analysis. And because the code on line, through the layers of testing, vulnerability is also easy to find, easy to find at least a short time. But others get your database information, then opened the God mode, like how to play how to play, do not delete the library on foot.

However, they fortunately found in time, the first time deleted items on github, but can not guarantee that no one pulled the project was local, so the second is to the configuration in the configuration file are changed again, change the configuration to listen it sounds simple, but be aware that some configuration is not hot update. After a lot of configuration make configuration changes before you can use old and new configuration can not coexist, you change the project would collapse instantly run must be down for maintenance can. To change the configuration they spend a lot of manpower and material resources and energy.

In fact, this painful lesson could have been avoided, to prevent leakage configuration, there are two common forms. One is to use the Configuration Center, the configuration is not saved locally, start time obtained from the distribution center, which should be the optimal solution. But many times the items you do not use the configuration center, streaking in the project configuration inside. This time you need to configure the local encrypted form to prevent leakage, the common framework is jasypt. It is also the subject of this article, did not talk much, just start and see if you are using jasypt be configured encryption.

rely

pom.xml

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

<build>
  <plugins>
    <plugin>
      <groupId>com.github.ulisesbocchio</groupId>
      <artifactId>jasypt-maven-plugin</artifactId>
      <version>3.0.0</version>
    </plugin>
  </plugins>
</build>

Explanation

If you use a spring boot then use jasypt is as simple as dependent on a jasypt-spring-boot-starter pack on it.

As jasypt-maven-plugin maven plugin is easy to configure the encryption and decryption of us, he would say later usage.

Configuration

application.properties

my.conf.test1=123
my.conf.test2=DEC(123)
# 记得看最佳实践
jasypt.encryptor.password=lE1rl5K$

Explanation

总共有三个配置,第一个配置 my.conf.test1 是不需要加密的配置,第二个配置 my.conf.test2 是需要加密的配置,要加密的内容是 123。注意他的格式的是 DEC(待加密内容)。第三个 jasypt.encryptor.password  配置是我们的加密私钥,默认使用的加密算法是 PBEWITHHMACSHA512ANDAES_256 ,这个密钥可以是任意字符串,而   lE1rl5K$ 只是我随机生成的,你可以自由发挥。

生成加密内容

好了,到目前为止,我们的配置还是明文的。my.conf.test2 是我们想加密的配置,他与 my.conf.test1 唯一的区别就是多了一个 DEC() 包裹,这算哪门子加密,其实我们还差一步。还记得我们上面加依赖的时候,配置了一个 Maven 插件吗?现在就是用到他的时候,在我们的项目目录路径下执行如下命令:

命令

 mvn jasypt:encrypt -Djasypt.encryptor.password="lE1rl5K$" 

注意在执行的时候,password 要换成你自己在上文配置的密钥。执行完后,看到终端输出了一大堆日志,然后就没有然后了。但是真的是这样吗?

你再打开 application.properties 看一下,有什么不一样的地方。

my.conf.test1=123
my.conf.test2=ENC(0ZWzuD2DH0BZ8ANGMZxQyC6wv84sQLJtE6u7bcRjU+DntbMgkBvE2Z4fSzKKhYN8)
jasypt.encryptor.password=lE1rl5K$

我们发现,三个配置中其它两个是原来的样子,但是 my.conf.test2 变了,首先格式从之前 DEC(xxx) 变成了 ENC(xxx) 。另外括号的 123 变成了 0ZWzuD2DH0BZ8ANGMZxQyC6wv84sQLJtE6u7bcRjU+DntbMgkBvE2Z4fSzKKhYN8

这其实就是配置加密后的样子。这条命令的功能其实很简单:

  1. 从配置文件中加载配置
  2. 从配置中找到有 DEC(xxx) 格式并且不是 jasypt 开头的配置
  3. 使用配置的密钥加密并覆盖配置为 ENC(加密后的值)

另外通过插件也可以解密,使用

mvn jasypt:decrypt -Djasypt.encryptor.password="lE1rl5K$"

执行这条命令会反过来,把 ENC(xxx) 内容的配置解密成 DEC(明文) 打印在控制台,注意是控制台,而不是把配置文件变回去,作者说这样是为了安全。

验证

TestController.java

/*
 *
 *  * *
 *  *  * blog.coder4j.cn
 *  *  * Copyright (C) 2016-2019 All Rights Reserved.
 *  *
 *
 */
package cn.coder4j.study.example.jasypt;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author buhao
 * @version TestController.java, v 0.1 2019-12-26 10:55 buhao
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @Value("${my.conf.test1}")
    private String confTest1;
    @Value("${my.conf.test2}")
    private String confTest2;

    @GetMapping("/getConf/{type}")
    @ResponseBody
    public Object getConfTest(@PathVariable Integer type) {
        if (type == 1) {
            return confTest1;
        } else {
            return confTest2;
        }
    }
}

说明

代码其实很简单,首先通过 @Value 的方式读取配置,同时把没有加密的配置与加密的配置都读出来,然后通过接口,当路径参数为 1 的时候返回没有经过加密的参数,当路径参数为 2 的时候返回加密过的参数。要是都返回 123 说明我们成功了。

为了方便验证,直接用 IDEA 的内置工具,下面是验证结果:

未加密的参数

image.png

经过加密的参数

image.png

结果如我们所料,加密成功。

获取配置的大致流程其中跟上面加密配置的流程大致反过来:

  1. 拦截获取配置的操作
  2. 如果拦截到的配置是 ENC(xxx) 格式
  3. 读取 jasypt.encryptor.password 密钥
  4. 通过密钥解密配置

最佳实践

密钥与配置分开保存

可以看到,通过 jasypt 十分的方便,第一依赖,第二配置,其中配置除加密内容外还有一个 jasypt.encryptor.password 。这个前文也说了是用于加密与解密的密码,通过它可以加解密配置。

image.png

回到开头,我们加密的目的是为了防止代码泄露的时候把配置一起给泄露出去了。配置是没有问题了,我们加密了,但是我们同时把密钥也放在配置文件中了。这相当于什么呢?就像你把门给锁了,但是钥匙还插在锁上。

所以密钥一定要跟配置分开保存,通常是通过启动命令传给应用,比如下面这种:

java -Djasypt.encryptor.password="password" -jar my-application.jar

如果再保险一点,可以把密钥放在环境变量中,再通过命令传给应用。

非对称加密

默认使用的加密算法为对称加密 HHMAC ,既然有对称那肯定也有非对称。

这里的对称与非对称指的是密钥的保存方式,对称加密是指的是加密与解密共用一个密钥,也就是说我用这个密钥即可以用来加密也可以用来解密。上一条说为了安全我们要把配置跟密钥分开保存,一般保存在两个地方,一个是线上服务器,一个是项目负责人的电脑上了,因为他要把配置从明文变成密文。为什么是项目负责人的电脑上,因为密钥不可能人手一份,那样又会增大泄露风险。

但是这样的话又会出来一种问题,一个项目涉及了太多配置,我加一个配置找下项目负责人帮我生成个密文,加一个生成一个,项目负责人变成工具人了。

This time we can be solved by asymmetric encryption way, the benefits of this approach is that there is a password, called a public key and a private key used to generate the public key to encrypt data, you can be assured of a bold hand, while the private key decrypt the work of running time on the server, due to limited space, the specific use of official documents can be viewed through the link at the end of the text.

Environmental isolation

Configuration is certainly differentiate between environments, some environments the security level is not so high, such as development and test environments, encryption is not necessary. The pre-production environment, we need to send and encryption, and recommend using a different key, to avoid security problems such maximum.

In fact, the relevant

  1. the Spring-the Boot-Jasypt  (Jasypt the github address, has a well-documented)
  2. This article DEMO  (article because of limited space, only show part of the code, the specific code has been uploaded github)

image.png

Guess you like

Origin www.cnblogs.com/kiwifly/p/12154346.html