百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

阿里巴巴Druid,轻松实现MySQL数据库连接加密

connygpt 2024-10-12 16:57 4 浏览

为什么要加密?

现在的开发习惯,无论是公司的项目还是个人的项目,都会选择将源码上传到 Git 服务器(GitHub、Gitee 或是自建服务器),但只要将源码提交到公网服务器就会存在源码泄漏的风险,而数据库配置信息作为源码的一部分,一旦出现源码泄漏,那么数据库中的所有数据都会公之于众,其产生的不良后果无法预期(比如某某酒店的信息)。

于是为了避免这种问题的产生,我们至少要对数据库的密码进行加密操作,这样即使得到了源码,也不会造成数据的泄露,也算保住了最后一块遮羞布。

如何加密?

对于 Java 项目来说,要想快速实现数据库的加密,最简单可行的方案就是使用阿里巴巴提供的 Druid 来实现加密

什么是Druid?

Druid(中文译为“德鲁伊”)是阿里巴巴开源的一款 Java 语言中最好的数据库连接池。Druid 提供了强大的监控和扩展功能,当然也包含了数据库的加密功能。

Druid 开源地址:https://github.com/alibaba/druid/

Druid可以做什么?

  1. Druid 可以监控数据库访问性能,Druid 内置提供了一个功能强大的 StatFilter 插件,能够详细统计 SQL 的执行性能,这对于线上分析数据库访问性能有帮助。
  2. 替换数据库连接池 DBCP 和 C3P0,Druid 提供了一个高效、功能强大、可扩展性好的数据库连接池。
  3. 数据库密码加密,直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver 和 DruidDataSource 都支持 PasswordCallback。
  4. SQL 执行日志,Druid 提供了不同的 LogFilter,能够支持 Common-Logging、Log4j 和 JdkLog,你可以按需要选择相应的 LogFilter,监控你应用的数据库访问情况。
  5. 扩展 JDBC,如果你要对 JDBC 层有编程的需求,可以通过 Druid 提供的 Filter-Chain 机制,很方便编写 JDBC 层的扩展插件。

对于本文来说,我们重点来看它的第 3 个特性,也就是使用 Druid 来实现数据库密码加密。

加密执行流程

在没有进行密码加密之前,项目的交互流程是这样的:

在使用了密码加密之后,项目的交互流程就变成了这样:

使用Druid实现加密

本示例运行环境:

Spring Boot 2.4.3

MySQL 5.7

Java 1.8

Idea 2020.1.3

1.添加Druid依赖

Maven 项目:

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

Gradle 项目:

compile 'com.alibaba:druid-spring-boot-starter:1.2.5'

获取 Druid 最新版本:https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter

2.生成密文

Druid 添加完成之后就可以借助 Druid 中提供的 ConfigTools 类来加密密码了,实现代码如下:

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

class MyTests {
    public static void main(String[] args) throws Exception {
        // 需要加密的明文命名
        String password = "youPassword"; // 【注意:这里要改为你自己的密码】
        // 调用 druid 生成私钥、公钥、密文
        ConfigTools.main(new String[]{password});
    }
}

以上代码执行的结果如下:

privateKey:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEApOjcMWSDzJiKVGmtcBBoQPtM9tVW2H2cnS6xZK7NrbzQXYWLQD2zefIrrx9vMvqRIHEqkmAHTuUcUXHgCxu0cwIDAQABAkAlqo5ItdWo0Jqf5zdXJlg5p2yP4HCiqCYyfKzF+2s9KEmgWZJWTctZDsgQ0iYUohORR59I+J4nabhel1x5/INpAiEA6jwSyFqMUPOh1XlrzNFek+RthOQ5n4+ALPo+vULayO0CIQC0O7JM9sIq+tg+jCGv+ypk6vbuRKY9m5W2rSRXapGm3wIgRHul3jAjIDPrF/f1HaAFL+Y0Yws7Ebyp8/yCRWF7iA0CIALbe20q8FMcHPeI4zPWCIsHCpkmb3hEkjAOOKhGIT8DAiAqiUuz92NqKeyjmOfons1ka65EzVwA3NDhZ6+IQcnuig== publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ== password:IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==

从上述结果可以看出,使用 ConfigTools 类会生成 3 部分的内容:

  1. privateKey:私钥,暂时不会用到,用于密码的加密;
  2. publicKey:公钥,用于密码的解密;
  3. password:加密之后的密码。

PS:要实现数据库的加密,主要使用的是 publicKey(公钥)和 password(密文),这就把明文转换成密文了。

3.添加配置

完成了以上操作之后,只需要将上一步生成的公钥密文添加到项目的配置文件 application.yml(或application.xml)中就实现了加密操作了,具体配置信息如下:

spring:
  # MySQL 配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      url: jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
      username: root
      password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==
      # encrypt config
      filters: config
      connect-properties:
        config.decrypt: true
        config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTo3DFkg8yYilRprXAQaED7TPbVVth9nJ0usWSuza280F2Fi0A9s3nyK68fbzL6kSBxKpJgB07lHFFx4AsbtHMCAwEAAQ==

其中 password 对应的是上一步生成的 password(密文),而 config.decrypt.key 对应的是上一步生成的 publicKey(公钥),如下图所示:

这里提供一个原始的配置文件,以便和加密后的配置文件进行比对:

4.注意事项-插着钥匙的锁

经过前面 3 步的配置之后,我们的程序就可以正常运行了,但这远没有结束!

在第 3 配置时,我们将密文和公钥都写入配置文件,这就会造成当有人拿到密文和公钥之后,就可以使用 Druid 将加密的密码还原出来了,这就好比一把插着钥匙的锁是极不安全的。

因此我们正确的使用姿势:是将公钥找一个安全的地方保存起来,每次在项目启动时动态将公钥设置到项目中,这样就可以有效的保证密码的安全了。

正确的配置文件

接下来我们将 Spring Boot 的公钥设置为配置项,在项目运行时再替换为具体的值,最终的安全配置信息如下:

spring:
  # MySQL 配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      url: jdbc:mysql://127.0.0.1:3306/testdb?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
      username: root
      password: IMgKm27bOHok3/+5aDL4jGBoVVZkpicbbM6pIXQppi3dI7h3jngSAqhqwqYnfuYpyVJ0k++q9xWWnHtd6sAWnQ==
      # encrypt config
      filters: config
      connect-properties:
        config.decrypt: true
        config.decrypt.key: ${spring.datasource.druid.publickey}

可以看出公钥被修改成“${spring.datasource.druid.publickey}”了,这就相当于使用占位符先把坑给占上,等项目启动时再更换上具体的值。

PS:“spring.datasource.druid.publickey”并非是固定不可变的 key,此 key 值用户可自行定义。

开发环境替换公钥

开发环境只需要在 Idea 的启动参数中配置公钥的值即可,如下图所示:

当我们输入正确的公钥值时程序可以正常运行,当输入一个错误的公钥值时就会提示解码失败,如下图所示:

生产环境替换公钥

生产环境在启动 jar 包时只需要动态设置公钥的值即可,参考以下命令:

java -jar xxx.jar --spring.datasource.druid.publickey=你的公钥

Druid运行原理

经过上述步骤之后,我们就完成 MySQL 密码的加密了,这样当 Spring Boot 项目启动时,Druid 的拦截器会使用密文和公钥将密码还原成真实的密码以供项目使用,当然这一切都无需人工干预(无需编写任何代码),Druid 已经帮我封装好了,我们只需要通过以上配置即可。

什么?你想知道 Druid 是如何通过密文和公钥还原出真实的密码的?

没问题,满足你,其实 ConfigTools 类中已经提供了相应实现,代码如下:

// 密文
String password = "VwH1mu2IUpqjfKTd+gSikiZgJTi+3Y5zFIFRfxYnH1UqHzm1K8TIHnMaV3TErBaGsVEaGV0e63pb0Ys3Wdm7Kg==";
// 公钥
String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWIEp19IM04sB+vQXnEOH9gFNFdL5TFGSEhORgHj4MnfTfBSNaOoSgCaM8BOpjiHmwuEb7LpvmXI1x/ymUvNzECAwEAAQ==";
// 还原成真实的密码
String result = ConfigTools.decrypt(publicKey, password);
System.out.println("最终结果:" + result);

总结

本文我们使用阿里巴巴开源的 Druid 实现了 MySQL 的密码加密,Druid 的加密过程非常方便,无需编写任何代码,只需要添加 Druid 依赖,再通过 Druid 的工具类生成密文,最后将密文配置到 application.yml 文件即可。项目在运行时会通过拦截器将密文转换成真正的密码,从而实现了 MySQL 密码的加密和解码的过程。

最后

原创不易,如果觉得本文对你有帮助,请点个赞再走呗。

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&amp;Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick &#39;n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...