赞
踩
出于对项目的安全考虑,经常需要对数据库的密码进行加密,本文我们将带大家从源码角度进行分析各个配置的作用,使用druid的自带工具对数据进行加密。
- public static void main(String[] args) {
- String password = "test";
- String[] arguments = new String[]{password};
- try {
- ConfigTools.main(arguments);
- } catch (Exception e) {
- log.info("生成密文失败,异常信息:{}", e);
- }
- }
运行后可以得到加密后的密码
- privateKey:MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAlxFiZMO5fD1kOIc/B7R+dUsJ5EsxCXqGAC3SpiAHm/397LgpKi613kPRkzidA7olwT34gkXX7HNQnvYBngRyaQIDAQABAkAxRDUfgYkzUF4n5UuT+rQnEnLGZhM28SNUWZ1SGi4BHAHfp5pbyMEzDD+84hc5r5Euk7HEGkuUt2HNRPq4cpERAiEA4BRm3kfpuVfqSjij3zJ7UdiE54oWeAnG2XiG1hJvdmUCIQCslm8wUxksDgcvNUjQN8Pp9VZCBUzInlppanVZyUB5tQIgUSER3YjL5n8eJKE9M6JjY86wz+P/Hpbrl/E7YGZsVMECIQCPAOtKkGBYJ5t+W1lk5gAYeGertraDuOpTVJm99srMzQIgHX7T20MexhBxokUIQiXuaB8Z9CflpQY7StP/cedt9Wk=
- publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJcRYmTDuXw9ZDiHPwe0fnVLCeRLMQl6hgAt0qYgB5v9/ey4KSoutd5D0ZM4nQO6JcE9+IJF1+xzUJ72AZ4EcmkCAwEAAQ==
- password:WCACUuMVJmu01PWDOUphY5Ms7CUhG80WHJi8KqyJpIrQsVEyX5prwedps2YbkJaScUGPApuX6ZiFawfWxaDDyw==
可以看出druid默认的工具类是采用非对称加密的方式进行加密的
其中private是自动生成的随机私密,我们需要关注的值有“publicKey”跟"password",需要保存好着两个值。
从源码中分析
com.alibaba.druid.pool.DruidDataSource#init方法中,遍历了我们所有的filter。
- for (Filter filter : filters) {
- filter.init(this);
- }
为了让揭秘生效,我们需要配置解密的拦截器
- spring:
- datasource:
- druid:
- filters: config
这点比较重要,开启后表示druid加载时会走过滤器com.alibaba.druid.filter.config.ConfigFilter,改过滤器将对加密密码进行解密,
- public boolean isDecrypt(Properties connectionProperties, Properties configFileProperties) {
- // 读取CONFIG_DECRYPT配置,看是否进行加密,只有设置为true才会对数据库进行揭秘
- String decrypterId = connectionProperties.getProperty(CONFIG_DECRYPT);
- if (decrypterId == null || decrypterId.length() == 0) {
- if (configFileProperties != null) {
- decrypterId = configFileProperties.getProperty(CONFIG_DECRYPT);
- }
- }
-
- if (decrypterId == null || decrypterId.length() == 0) {
- decrypterId = System.getProperty(SYS_PROP_CONFIG_DECRYPT);
- }
-
- return Boolean.valueOf(decrypterId);
- }
从上面源码中可以看出,我们还需要配置一个CONFIG_DECRYPT,设置为true。
- spring:
- datasource:
- druid:
- connect-properties:
- config.decrypt: true
此时会走解密流程,此时会调用com.alibaba.druid.filter.config.ConfigFilter#decrypt方法。
解读decrypt的方法可以看出,我们还需要配置解密的公钥配置
- spring:
- datasource:
- druid:
- config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALwTQSulMoXLHIiwpXY7V1LdLzAusZ3zPOdEHD0fSn6Nc51UAHjRli+pxgIt6M899mXhZ9k2aGzE5weuf9uNTfcCAwEAAQ==
这个公钥就是上面我们main生成的publicKey。配置好公钥后,进行我们的密码解密操作。
此时会读取我们配置的加密后的密码
- spring:
- datasource:
- druid:
- password: JjtSWRv9rPnksKAvLZwFuxkpYxbyBxJKFhe5aZGo90BS7HbbQhtEvGCEt75aqDYcyzkkvOfYSxQ5sFKoURWRBQ==
这个password就是我们上面运行main方法生成的加密密码。
由于项目中有的用的是多数据源配置:
首先应用baomidou的多数据源maven
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
- <version>3.5.0</version>
- </dependency>
对于多数据源我们需要关注
com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration类,该类加载了多数据源的配置com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties
从配置中,我们可以看出有专门的druid的一个节点
- /**
- * Druid全局参数配置
- */
- @NestedConfigurationProperty
- private DruidConfig druid = new DruidConfig();
查看com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidConfig#toProperties中源码:
- // 通过判断publicKey值来判断是否加过滤器
- if (publicKey != null && publicKey.length() > 0 && !filters.contains(CONFIG_STR)) {
- filters += "," + CONFIG_STR;
- }
- properties.setProperty(FILTERS, filters);
可以看出,我们需要配置一个publicKey,这个key就是我们上面main生成的公钥。
继续阅读下面的代码,会发现利用pulicKey还做了以下事情
- Properties connectProperties = connectionProperties == null ? g.getConnectionProperties() : connectionProperties;
-
- // 自动拼接config.decrypt跟config.decrypt.key
- if (publicKey != null && publicKey.length() > 0) {
- if (connectProperties == null) {
- connectProperties = new Properties();
- }
- connectProperties.setProperty("config.decrypt", Boolean.TRUE.toString());
- connectProperties.setProperty("config.decrypt.key", publicKey);
- }
- this.connectionProperties = connectProperties;
从上面的代码中,可以看出,自动帮我们配置了config.decrypt跟config.decrypt.key,所以我们不需要跟配置druid一样去配置这两个属性,默认开启解密。
此时我们的密码加密就完成了。
总结一下,需要对数据库数据库进行加密,我们需要进行配置四个个地方。如下
- spring:
- datasource:
- druid:
- filters: config #配置过滤器
- password: ${password} #加密的密钥
- connect-properties:
- config.decrypt: true #设置为true,开启解密
- config.decrypt.key: ${publicKey} #解密的公钥
对于使用的baomidou的多数据源,我们需要配置两个地方,如下:
- spring:
- datasource:
- dynamic:
- enabled: true
- primary: master
- datasource:
- master:
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://url/dbname?useUnicode=true&characterEncoding=utf-8&
- username: test
- password: ${passord} #加密的密码
- driver-class-name: com.mysql.jdbc.Driver
- druid:
- filters: config #开启过滤器
- publicKey: ${publicKey} #生成的公钥
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。