You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi TADOConnection连接字符串的安全处理方案问询

问题背景与解决方案

问题概述

基于Delphi 10.4开发的30年Windows桌面应用,使用单个TADOConnection组件,设计时关联了约100个TADOQuery等数据组件,仅在运行时设置ConnectionString(含Persist Security Info=True),已稳定运行数十年。近期引入模仿C# SecureString的TSecureString存储敏感字符串,仅在赋值给TADOConnection.ConnectionString时转为明文,但企业IT安全扫描发现:应用登录后主界面未执行SQL时,内存中仍存在明文连接字符串。

已尝试的无效方案:

  • 使用OnWillConnect事件修改用户名/密码:仅登录时设置Connected=True一次,若不保持连接需大量改造代码,不可行。
  • 使用OnWillExecute事件修改连接字符串:触发“对象打开时不允许操作”错误。
  • 设置Persist Security Info=False:无法在SQL执行时修改用户名/密码,不符合需求。

需求:在不重大改造应用(即将退役)的前提下,实现全局使用TADOConnection且隐藏内存中明文连接字符串的最优方案;若TADOConnection本身支持隐藏/加密内存中的连接字符串,需提供文档依据。

可行解决方案

方案1:连接建立后主动覆盖内存(最低改造量)

  • 核心逻辑:ADODB连接建立后,ConnectionString的明文仅用于初始会话建立,后续SQL执行依赖已建立的连接会话,因此可主动覆盖内存中的明文连接字符串,不影响现有功能。
  • 操作步骤:
    1. 在TADOConnection的AfterConnect事件中,通过ConnectionObject获取原生ADODB连接实例,调用ConnectionString属性传入空字符串或占位符,覆盖内存中的明文。
    2. 示例代码:
      procedure TMainForm.ADOConnection1AfterConnect(Sender: TObject);
      var
        ADODBConn: ADODB.Connection;
      begin
        ADODBConn := ADODB.Connection(ADOConnection1.ConnectionObject);
        // 覆盖内存中的明文连接字符串,不影响已建立的连接
        ADODBConn.ConnectionString := '';
        // 若后续需要重连,提前用TSecureString保存原始连接字符串
      end;
      
  • 优势:仅需添加一个事件处理,无需修改现有100个数据组件的关联逻辑,改造量极小。

方案2:轻量封装自定义ADO连接类

  • 核心逻辑:继承TADOConnection,重写SetConnectionString方法,在赋值后立即覆盖内部存储的明文,同时用TSecureString保存原始加密连接串,方便后续重连。
  • 操作步骤:
    1. 创建自定义连接类:
      type
        TSecureADOConnection = class(TADOConnection)
        private
          FSecureConnStr: TSecureString;
        protected
          procedure SetConnectionString(const Value: WideString); override;
        public
          property SecureConnStr: TSecureString read FSecureConnStr write FSecureConnStr;
          procedure Reconnect;
        end;
      
      procedure TSecureADOConnection.SetConnectionString(const Value: WideString);
      begin
        inherited;
        // 连接建立后覆盖明文
        if Connected then
          inherited SetConnectionString('');
        // 保存加密后的连接串
        FSecureConnStr.Assign(Value);
      end;
      
      procedure TSecureADOConnection.Reconnect;
      var
        PlainStr: string;
      begin
        Disconnect;
        PlainStr := FSecureConnStr.ToPlainText;
        try
          ConnectionString := PlainStr;
          Connected := True;
        finally
          // 清除临时明文
          FillChar(PlainStr[1], Length(PlainStr) * SizeOf(Char), 0);
        end;
      end;
      
    2. 将原项目中的TADOConnection组件替换为TSecureADOConnection(仅需设计时替换组件类型,无需修改关联的查询组件)。
  • 优势:封装后无需重复编写内存覆盖逻辑,重连时可直接从加密串恢复,符合现有代码习惯。

TADOConnection原生加密支持说明

根据Embarcadero官方文档,TADOConnection本身不提供内存中连接字符串的自动加密功能,其内部直接存储传入的明文ConnectionString;ADODB原生Connection对象在Persist Security Info=True时会主动保留明文凭证,这也是内存中出现明文的核心原因,无原生隐藏/加密机制。

内容的提问来源于stack exchange,提问作者Bond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:55:23