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执行依赖已建立的连接会话,因此可主动覆盖内存中的明文连接字符串,不影响现有功能。 - 操作步骤:
- 在
TADOConnection的AfterConnect事件中,通过ConnectionObject获取原生ADODB连接实例,调用ConnectionString属性传入空字符串或占位符,覆盖内存中的明文。 - 示例代码:
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保存原始加密连接串,方便后续重连。 - 操作步骤:
- 创建自定义连接类:
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; - 将原项目中的
TADOConnection组件替换为TSecureADOConnection(仅需设计时替换组件类型,无需修改关联的查询组件)。
- 创建自定义连接类:
- 优势:封装后无需重复编写内存覆盖逻辑,重连时可直接从加密串恢复,符合现有代码习惯。
TADOConnection原生加密支持说明
根据Embarcadero官方文档,TADOConnection本身不提供内存中连接字符串的自动加密功能,其内部直接存储传入的明文ConnectionString;ADODB原生Connection对象在Persist Security Info=True时会主动保留明文凭证,这也是内存中出现明文的核心原因,无原生隐藏/加密机制。
内容的提问来源于stack exchange,提问作者Bond
相关产品推荐
相关产品推荐

