SpringBoot中Druid加密数据连接信息

现在SpringBoot做web开发经常用到Druid做数据源,但数据库连接的相关信息比如usernamepassword等关键信息有时候直接写在配置文件中,容易暴露,虽然也可以用指定外部配置文件的方式避免生产环境敏感数据泄露,但其实Druid还内置了数据库加密功能。

1. druid依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.22</version>
</dependency>

2. 生成加密后的连接信息

import com.alibaba.druid.filter.config.ConfigTools;

@Test
public void testEncrypt() throws Exception {
    String password = "123456";
    ConfigTools.main(new String[]{password});
}

输出结果:

privateKey:MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAoWVj3PyjACvyzeOkPq79TdkcvmcHeOw/Vm7eUPC7SRrJ8wFkjCFEWsxInBFO7HAe0cjTNOI7P39IA45DmxCntwIDAQABAkEAgwEVii7W8DC8KTr5+pd3rFTq6/IdMp4w2yuq8PA2VSNC4QbVBfBSLBorZLvwiWrokiC44zULrsb8HzdcMKmPIQIhAP9n1ammYQxKryrr3KAD/sAk9JYPup5ZZA7ZNTinDANtAiEAocWL6QjzrCye5iOq/CZkAEUu48n6v1s/EkBfL65nPTMCIFCDt0OIA8gQMzBgsmhvWfvQqpoz0yzgGT7lEnYNkyfxAiADqH3zdRpdiFzHg4L4VL3qK6ZVzFl5Pkz80qvUXjNDdQIgGDdsK68goZG5IHdJTVTwW5S3Z2XcGFDI7gQ20rskBIY=
publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKFlY9z8owAr8s3jpD6u/U3ZHL5nB3jsP1Zu3lDwu0kayfMBZIwhRFrMSJwRTuxwHtHI0zTiOz9/SAOOQ5sQp7cCAwEAAQ==
password:jbj2tfygiIdcrA8NaxBd8HL/967fN7QSxDPXxqG1diezq3g0PnWrpyYdv0OxM1Ra/RyZaPg3Ik5cr8HOsMFXvg==

privateKey ==> 私钥(没用到)
publicKey ==> 公钥
password ==> 密文


3. 修改连接配置

先看常规版明文连接配置信息:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test
      username: root
      password: 123456

改成加密连接配置信息:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test
      username: root
      # password 改成生成的 password(密文)
      password: jbj2tfygiIdcrA8NaxBd8HL/967fN7QSxDPXxqG1diezq3g0PnWrpyYdv0OxM1Ra/RyZaPg3Ik5cr8HOsMFXvg==
      # 新增以下内容
      filters: config
      connect-properties:
        config.decrypt: true
        # config.decrypt.key 对应生成的 publicKey(公钥)
        config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKFlY9z8owAr8s3jpD6u/U3ZHL5nB3jsP1Zu3lDwu0kayfMBZIwhRFrMSJwRTuxwHtHI0zTiOz9/SAOOQ5sQp7cCAwEAAQ==

这个时候已经可以正常使用了,但还没有做到安全

因为这个“锁”跟“钥匙”都放在一个地方,并不安全,正确操作方式是将passwordconfig.decrypt.key配置成变量,在生产环境通过环境变量的方式传递进去即可,因此最终修改成如下形式:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/test
      username: root
      password: ${db.password}
      filters: config
      connect-properties:
        config.decrypt: true
        config.decrypt.key: ${db.publicKey}

在生产环境启动时,传递变量进去,例如:

java -jar xxx.jar --db.password=密文 --db.publicKey=公钥

一般SpringBoot项目的配置文件都会区分多个环境,比如devprod 等,为了便于开发,dev环境就可以直接明文,而prod环境就启用连接加密即可


4. 密码的还原

由于Druid的拦截器会在SpringBoot项目启动时自动将密文跟公钥还原成真实密码,因此配置完加密后无需再改别处。但我们可以直接通过代码的方式,基于密文跟公钥还原真实密码,依旧是使用ConfigTools

import com.alibaba.druid.filter.config.ConfigTools;

@Test
public void testDecrypt() throws Exception {
    String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIF+TFbqgRWPF5ojWHmqMkyzDS08BDxe7aSB8tUaAaZReF9QJNU6MT+LyAhTQe71NXPwwP/9FpfXWJyxpYjQTe0CAwEAAQ==";
    String password = "VqhrppUJ7BeLAnO6Juf1I0u6rDpXFvSV4/anW8qxI5QF9ip1ClPdvIcX4BS5sUz5wvtBygx4mAYjOh0CajEgrQ==";
    String result = ConfigTools.decrypt(publicKey, password);
    System.out.println("result:" + result);
}

结果:

result:123456

还原正常


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章