天呐,你生产环境中的密码还在裸奔吗?

2021-01-04 14:54:31 浏览数 (1)

每一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。

放弃不难,但坚持很酷~

1

先看一份典型的配置文件

代码语言:javascript复制
.. 省略 ...

## 配置MySQL数据库连接
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.xx.xxx:3306/test?createDatabaseIfNotExist=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
    username: root
    password: 123456

... 省略 ...

这是节选自某个典型的 Spring Boot 项目的 application.yml 配置文件。

嘘... 偷偷告诉我,是不是很多小伙伴也都是这么写的?

这乍一看没啥问题,很多人会觉得理所当然。包括我自己也看到过很多的项目(包括很多开源项目)是这么写的。

但仔细一琢磨,发现里面有明文密码呀,这是不是就很危险?!尤其你的项目要是上传到 github 公共库的话,是可以被任何人查阅的,如果这样导致自己或公司的数据库泄露,后果可想而知。。。

总而言之,在配置文件中的所有密码都应该做加密处理。今天我们就来讲一下加密组件 Jasypt 这个强大的库。

2

引入依赖

代码语言:javascript复制
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

3

配置加密相关参数

方式一:使用 properties 文件配置

代码语言:javascript复制
jasypt.encryptor.algorithm=PBEWithMD5AndDES   # 默认的加密方式,还可以是PBEWithMD5AndTripleDES
jasypt.encryptor.password=jasypt   # 加解密所需的salt(盐)
jasypt.encryptor.property.prefix=ENC(   # 标记密文的前缀
jasypt.encryptor.property.suffix=)    # 标记密文的后缀

方式二:使用 yml 文件配置

代码语言:javascript复制
jasypt:
  encryptor:
    password: jasypt
    algorithm: PBEWithMD5AndDES
    property: 
        prefix: ENC(
        suffix: )

方式三:使用启动参数配置(为了防止salt(盐)泄露,反解出密码。可以在项目部署的时候作为参数传入salt(盐)值,推荐使用

1)idea 配置方法

2)启动 jar 包命令:

代码语言:javascript复制
java -Djasypt.encryptor.password=jasypt -jar xxx.jar

上面的 jasypt.encryptor.password 配置是指定 jasypt 加解密明文的密钥。即:jasypt 会根据该值加密你的明文,然后你将密文配置在配置文件中显示;程序启动的时候,jasypt 会将你的密文根据密钥解密,进行验证。

4

两种生成密文的方式

方式一:使用 spring boot 单元测试

代码语言:javascript复制
import org.jasypt.encryption.StringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class JasyptTest {

    @Autowired
    private StringEncryptor stringEncryptor;

    @Test
    public void encryptPwd() {
        //加密123456
        String result = stringEncryptor.encrypt("123456");
        System.out.println(result);
    }
}

在单元测试中,spring boot 会读取 application 配置文件中的 jasypt.encryptor.password ,对明文 123456 进行加密。

方式二:使用工具类

代码语言:javascript复制
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;

/**
* Jasypt加密工具类
*/
public class JasyptUtil {

    /**
     * Jasypt生成加密结果
     * @param password 配置文件中设定的加密密
     * @param value 加密值
     * @return
     */
    public static String encyptPwd(String password,String value){
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(cryptor(password));
        String result = encryptor.encrypt(value);
        return result;
    }

    /**
     * 解密
     * @param password 配置文件中设定的加密密码
     * @param value 解密密文
     * @return
     */
    public static String decyptPwd(String password,String value){
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(cryptor(password));
        String result = encryptor.decrypt(value);
        return result;
    }

    public static SimpleStringPBEConfig cryptor(String password){
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(password);
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");
        return config;
    }

    public static void main(String[] args){
        //加密
        System.out.println(encyptPwd("jasypt","123456"));
        //解密
        System.out.println(decyptPwd("jasypt","lnzpDZItgjAntHqsYPFTew=="));
    }
}

5

配置密文

将生成的加密密文配置在配置文件中即可,如示例所示,密文已用 test() 所标记,在启动时会解析所有 jasypt.encryptor.property.prefix/suffix 标记的密文。

示例:

代码语言:javascript复制
jasypt:
  encryptor:
    password: jasypt
    algorithm: PBEWithMD5AndDES
    property: 
        prefix: test(
        suffix: )spring:
  datasource:
    password: test(lnzpDZItgjAntHqsYPFTew==)

6

嘘... 快去加密

好了,说了这么多,如果你项目的配置文件中的重要信息没有加密的话,答应我,二话别说,赶快全部偷偷去改掉,快!速度!跑步前进!

0 人点赞