Druid连接池实现自定义数据库密码加解密功能详解

news2025/6/7 22:44:49

Druid连接池实现自定义数据库密码加解密功能详解

在企业级应用开发中,数据库密码的明文存储是一个显著的安全隐患。Druid作为阿里巴巴开源的高性能数据库连接池组件,提供了灵活的密码加密与解密功能,允许开发者通过自定义逻辑实现数据库密码的加密存储与动态解密。本文将详细介绍如何基于Druid连接池实现自定义的数据库密码加解密功能,并结合Spring Boot框架进行集成,帮助开发者提升系统的安全性。


一、背景与需求

1. 问题场景

在传统Spring Boot项目中,数据库密码通常以明文形式存储在application.ymlapplication.properties配置文件中。这种做法存在以下风险:

  • 配置文件泄露:若配置文件被恶意获取,攻击者可直接读取数据库密码。
  • 权限滥用:开发人员或运维人员在调试时可能误操作敏感信息。
  • 合规性要求:部分行业标准(如GDPR)要求敏感数据必须加密存储。

2. Druid的解决方案

Druid通过以下机制支持密码加密:

  • 内置加密工具:提供ConfigTools工具类,支持使用AES算法加密密码。
  • 自定义回调逻辑:允许开发者通过继承DruidPasswordCallback或自定义DruidDataSource实现密码解密逻辑。
  • Spring Boot集成:通过配置DruidDataSourcepasswordCallback属性或自定义初始化器,实现密码的动态解密。

二、实现步骤

1. 生成加密密码

Druid提供了命令行工具ConfigTools,用于生成加密后的密码和密钥。

步骤
  1. 准备Druid JAR包:确保本地已下载Druid的JAR文件(如druid-1.2.18.jar)。
  2. 执行加密命令
    java -cp druid-1.2.18.jar com.alibaba.druid.filter.config.ConfigTools your_password
    
    执行后,输出包含加密后的密码、公钥(publicKey)和私钥(privateKey)。
    Encrypted Password: e9b7f4a5c0d6df71aefbacd7bb6434ea
    Public Key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIcJxWEMHcqBNY7FKX7RufzMNhll8NRG9GAdP6/QbQQQbT0QIgMol0lW57AUK9/Vzhr6VfgdqLQ1h2Zy8YTOXJ8ECAwEAAQ==
    Private Key: MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggFAMB8...
    
  3. 保存密钥与加密密码
    • 将加密后的密码替换到配置文件中的spring.datasource.password字段。
    • 将私钥(privateKey)存储在安全的位置(如服务器环境变量或加密配置中心)。

2. 自定义密码解密逻辑

方法一:通过DruidPasswordCallback回调类

Druid允许通过实现DruidPasswordCallback接口,在连接初始化时动态解密密码。

代码示例
  1. 创建回调类

    package com.example.druid;
    
    import com.alibaba.druid.util.DruidPasswordCallback;
    import java.util.Properties;
    
    public class CustomPasswordCallback extends DruidPasswordCallback {
        @Override
        public void setProperties(Properties properties) {
            super.setProperties(properties);
            String encryptedPassword = properties.getProperty("password");
            if (encryptedPassword != null) {
                // 调用自定义解密方法
                String decryptedPassword = decrypt(encryptedPassword);
                setPassword(decryptedPassword.toCharArray());
            }
        }
    
        private String decrypt(String encryptedPassword) {
            // 示例:使用AES解密
            String privateKey = "MIIBVgIBADANBgkqhkiG9w0BAQEFAASC...";
            return AESUtil.decrypt(encryptedPassword, privateKey);
        }
    }
    
  2. 配置Spring的DruidDataSource

    <bean id="dbPasswordCallback" class="com.example.druid.CustomPasswordCallback" lazy-init="true"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="e9b7f4a5c0d6df71aefbacd7bb6434ea"/> <!-- 加密后的密码 -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="passwordCallback" ref="dbPasswordCallback"/>
    </bean>
    
方法二:继承DruidDataSource并重写setPassword方法

在Spring Boot项目中,可通过自定义DruidDataSource实现密码解密。

代码示例
  1. 自定义数据源类

    package com.example.druid;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomDruidDataSource extends DruidDataSource {
        @Override
        public void setPassword(String password) {
            try {
                // 使用自定义解密方法
                String decryptedPassword = AESUtil.decrypt(password, "your-secret-key");
                super.setPassword(decryptedPassword);
            } catch (Exception e) {
                throw new RuntimeException("Password decryption failed", e);
            }
        }
    }
    
  2. 配置Spring Boot数据源

    spring:
      datasource:
        type: com.example.druid.CustomDruidDataSource
        url: jdbc:mysql://localhost:3306/mydb
        username: root
        password: e9b7f4a5c0d6df71aefbacd7bb6434ea  # 加密后的密码
    

3. 加密算法实现

Druid默认使用AES算法进行加密,开发者可根据需求选择其他算法(如RSA)。

AES加密示例
public class AESUtil {
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }

    public static String decrypt(String encryptedData, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedBytes);
    }
}

三、注意事项

1. 密钥管理

  • 安全存储:私钥应存储在服务器环境变量、加密配置中心(如Nacos)或专用密钥管理服务(如AWS KMS)中,避免硬编码在代码中。
  • 定期更新:定期更换加密密钥,并重新生成加密密码,降低长期密钥泄露风险。

2. 配置文件保护

  • 限制访问权限:确保配置文件的存储目录权限仅限于必要人员访问。
  • 使用加密配置中心:在Spring Cloud生态中,可通过Spring Cloud Config或Nacos实现配置文件的动态加密与解密。

3. 测试与验证

  • 单元测试:编写单元测试验证加密与解密逻辑的正确性。
  • 集成测试:启动应用后,通过数据库连接测试(如执行简单查询)确认密码解密功能生效。

四、总结

通过Druid连接池的自定义密码加解密功能,开发者可以有效规避数据库密码明文存储的风险。本文介绍了两种常见的实现方式:

  1. 基于DruidPasswordCallback的回调机制:适用于传统Spring项目,通过继承回调类实现动态解密。
  2. 自定义DruidDataSource:适合Spring Boot项目,通过重写方法集成加密逻辑。

在实际应用中,需结合项目需求选择合适的实现方案,并严格遵循密钥管理规范,确保系统的安全性与稳定性。通过合理配置,开发者可在不牺牲性能的前提下,显著提升数据库连接的安全性。


参考资源

  • Druid官方文档
  • Spring Boot与Druid集成指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OS11.【Linux】vim文本编辑器

目录 1.四种模式 命令模式 几个命令 插入模式 底行模式 一图展示三种模式之间的关系 2.分屏(多文件操作) 3.配置vim的原理 4.脚本一键配置vim CentOS 7 x86_64 其他发行版 5.NeoVim(推荐) vim文本编辑器是一个多模式的编辑器,因此先介绍它的四种模式 附vim的官网:…

基于SFC的windows系统损坏修复程序

前言 在平时使用Windows操作系统时会遇到很多因为系统文件损坏而出现的错误 例如:系统应用无法打开 系统窗口(例如开始菜单)无法使用 电脑蓝屏或者卡死 是如果想要修复很多人只能想到重装系统。但其实Windows有一个内置的系统文件检查器可以修复此类错误。 原理 SFC命令…

WAF绕过,网络层面后门分析,Windows/linux/数据库提权实验

一、WAF绕过文件上传漏洞 win7&#xff1a;10.0.0.168 思路&#xff1a;要想要绕过WAF&#xff0c;第一步是要根据上传的内容找出来被拦截的原因。对于文件上传有三个可以考虑的点&#xff1a;文件后缀名&#xff0c;文件内容&#xff0c;文件类型。 第二步是根据找出来的拦截原…

Vue 3 弹出式计算器组件(源码 + 教程)

&#x1f9ee; Vue 3 弹出式计算器组件&#xff08;源码 教程&#xff09; &#x1f4cc; 建议收藏 点赞 关注&#xff0c;本组件支持加减乘除、双向绑定、计算过程展示&#xff0c;适用于表单辅助输入场景。 &#x1f527; 一、完整源码&#xff08;复制即用&#xff09; …

监测预警系统重塑隧道安全新范式

在崇山峻岭的脉络间延伸的隧道&#xff0c;曾是交通安全的薄弱环节。智慧隧道监测预警系统的诞生&#xff0c;正在彻底改变这种被动防御格局&#xff0c;通过数字神经网络的构建&#xff0c;为地下交通动脉注入智能守护基因。 一、安全防控体系的质变升级 1.风险感知维度革命…

技巧小结:外部总线访问FPGA寄存器

概述 需求&#xff1a;stm32的fsmc总线挂载fpga&#xff0c;stm32需要访问fpga内部寄存器 1、分散加载文件将变量存放到指定地址即FPGA寄存器地址 sct文件指定变量存储地址&#xff0c;从而可以直接访问外设&#xff0c;&#xff08;28335也可以&#xff0c;不过用的是cmd文件…

jenkins集成gitlab发布到远程服务器

jenkins集成gitlab发布到远程服务器 前面我们讲了通过创建maven项目部署在jenkins本地服务器&#xff0c;这次实验我们将部署在远程服务器&#xff0c;再以nginx作为前端项目做一个小小的举例 1、部署nginx服务 [rootweb ~]# docker pull nginx [rootweb ~]# docker images …

当主观认知遇上机器逻辑:减少大模型工程化中的“主观性”模糊

一、人类与机器的认知差异 当自动驾驶汽车遇到紧急情况需要做出选择时&#xff0c;人类的决策往往充满矛盾&#xff1a;有人会优先保护儿童和老人&#xff0c;有人坚持"不主动变道"的操作原则。这种差异背后&#xff0c;体现着人类特有的情感判断与价值选择。而机器的…

会计 - 金融负债和权益工具

一、金融负债和权益工具区分的基本原则 (1)是否存在无条件地避免交付现金或其他金融资产的合同义务 如果企业不能无条件地避免以交付现金或其他金融资产来履行一项合同义务,则该合同义务符合金融负债的义务。 常见的该类合同义务情形包括:- 不能无条件避免的赎回; -强制…

Dify工具插件开发和智能体开发全流程

想象一下&#xff0c;你正在开发一个 AI 聊天机器人&#xff0c;想让它能实时搜索 Google、生成图像&#xff0c;甚至自动规划任务&#xff0c;但手动集成这些功能耗时又复杂。Dify 来了&#xff01;这个开源的 AI 应用平台让你轻松开发工具插件和智能体策略插件&#xff0c;快…

AI书签管理工具开发全记录(十三):TUI基本框架搭建

文章目录 AI书签管理工具开发全记录&#xff08;十三&#xff09;&#xff1a;TUI基本框架搭建前言 &#x1f4dd;1.TUI介绍 &#x1f50d;2. 框架选择 ⚙️3. 功能梳理 &#x1f3af;4. 基础框架搭建⚙️4.1 安装4.2 参数设计4.3 绘制ui4.3.1 设计结构体4.3.2 创建头部4.3.3 创…

初识结构体,整型提升及操作符的属性

目录 一、结构体成员访问操作符1.1 结构体二、操作符的属性&#xff1a;优先级、结合性2.1 优先级2.2 结合性C 运算符优先级 三、表达式求值3.1 整型提升3.2 算数转化 总结 一、结构体成员访问操作符 1.1 结构体 C语言已经提供了内置类型&#xff0c;如&#xff1a;char,shor…

检测到 #include 错误。请更新 includePath。已为此翻译单元(D:\软件\vscode\test.c)禁用波形曲线

原文链接&#xff1a;【VScodeMinGw】安装配置教程 下载mingw64 打开可以看到bin文件夹下是多个.exe文件&#xff0c;gcc.exe地址在环境配置中要用到 原文链接&#xff1a;VSCode中出现“#include错误&#xff0c;请更新includePath“问题&#xff0c;解决方法 重新VScode后…

2025年,百度智能云打响AI落地升维战

如果说从AI到Agent是对于产品落地形态的共识&#xff0c;那么如今百度智能云打响的恰是一个基于Agent进行TO B行业表达的AI生产力升维战。 在这个新的工程体系能力里&#xff0c;除了之前百度Create大会上提出的面向Agent的RAG能力等通用能力模块&#xff0c;对更为专业、个性…

Seed1.5-VL登顶,国产闭源模型弯道超车丨多模态模型5月最新榜单揭晓

随着图像、文本、语音、视频等多模态信息融合能力的持续增强&#xff0c;多模态大模型在感知理解、逻辑推理和内容生成等任务中的综合表现不断提升&#xff0c;正在展现出愈发接近人类的智能水平。多模态能力也正在从底层的感知理解&#xff0c;迈向具备认知、推理、决策能力的…

第3章——SSM整合

一、整合持久层框架MyBatis 1.准备数据库表及数据 创建数据库&#xff1a;springboot 使用IDEA工具自带的mysql插件来完成表的创建和数据的准备&#xff1a; 创建表 表创建成功后&#xff0c;为表准备数据&#xff0c;如下&#xff1a; 2.创建SpringBoot项目 使用脚手架创建…

VTK 显示文字、图片及2D/3D图

1. 基本环境设置 首先确保你已经安装了VTK库&#xff0c;并配置好了C开发环境。 #include <vtkSmartPointer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> 2. 显示文字 2D文字 #include &l…

小白如何在cursor中使用mcp服务——以使用notion的api为例

1. 首先安装node.js,在这一步的时候不要勾选不要勾选 2. 安装完之后,前往notion页面 我的创作者个人资料 | Notion 前往集成页面&#xff0c;添加新集成&#xff0c;自己输入名字&#xff0c;选择内部 新建完之后&#xff0c;进入选择只读 复制密匙 然后前往cursor页面 新建…

引领AI安全新时代 Accelerate 2025北亚巡展·北京站成功举办

6月5日&#xff0c;网络安全行业年度盛会——"Accelerate 2025北亚巡展北京站"圆满落幕&#xff01;来自智库、产业界、Fortinet管理层及技术团队的权威专家&#xff0c;与来自各行业的企业客户代表齐聚一堂&#xff0c;围绕"AI智御全球引领安全新时代"主题…

为什么说数列是特殊的函数

文章目录 前情概要函数特性特殊之处典例剖析前情概要 高三的学生几乎都听老师说过,数列是特殊的函数,那么如何理解这句话呢,无外乎需要关注两点:①函数性,②特殊性,以下举例说明,帮助各位学子理解。 函数特性 既然是按照一定的次序排列而成的一列数字,那么这些数字(…