☰
Delphi 13.1集成SecureBridge:SSH/SFTP组件安装与避坑指南
2026/10/10 7:54:22 网站建设 项目流程

简介:SecureBridge v11.0.1 专业版是面向 Delphi 与 C++Builder 开发者的网络通信安全组件库,基于 SSH/SSL 协议提供数据加密、身份验证和授权机制,可嵌入桌面、数据库、Web 及移动应用开发流程,解决网络传输中的安全防护问题,适合需要高强度通信加密的中高级程序员。压缩包内共 938 个文件,大小约 2.86MB,涵盖 153 个 Pascal 源码、123 个 inc 头文件、86 个 dpk 工程文件、51 个 dfm 窗体文件,以及 Demos 示例、Lib 库、Include 头文件、界面图标和配置脚本等;另附 HTML/CHM 帮助文档、安装说明图、许可协议与编译脚本,目录结构清晰,便于用于组件编译和项目集成。目前已有 33 人学习下载。从源码到示例再到库文件,这套资料提供了完整的 SecureBridge 使用链路。开发者既可查阅 Pascal 源码理解加密流程,也可运行 Demos 工程快速上手,还能利用 Lib 与 Include 完成本地编译,减少自行排查环境的时间成本。对于计划在 Delphi 项目中引入 SSH/SSL 安全通信的团队或个人,是一份实用性较高的参考包。

1. 一个压缩包解决 Delphi 的 SSH/SFTP 缺口

前些天客户让 Delphi 程序定时把报表推到内网 Linux 服务器,我打开组件面板翻了半天,发现引入的 Indy 自带的 SSH 组件根本顶不上用。

正当我以为又要用 plink.exe 拉起命令行打工时,想起了这个在很多 Delphi 开发者硬盘里躺了很久的压缩包:Devart SecureBridge v11.0.1 Professional。它解决的就是这样一件事:给 Delphi 13.1(RAD Studio 13.1)装上一整套 SSH、SFTP、SCP 和端口转发控件,装完之后 IDE 组件面板会多出一页,从 TScSSHClient 到 TScSFTP 齐全了。你不用再维护外部命令行、解析 stdout、跟不同编码搏斗,直接在 Object Pascal 里写连接、传文件、做隧道。这篇按我实际装机和排障的顺序来:为什么选它、从 .7z 装进 IDE 面板怎么做、第一段能跑的密码认证代码怎么写,以及那几个躲不开的坑。

2. 为什么是 SecureBridge:SSH 组件选型要看的 4 个硬指标

2.1 原生 Indy 的 SSH 为什么没法直接拿来用

很多 Delphi 老用户的第一反应是“Indy 里不是有 TIdSSH 和 TIdSFTP 吗”。确实有,但你在 Delphi 13.1 里把 TIdSSH 拖到窗体上,再翻一下它的实现,会发现这只是一个能碰运气握手的实验组件。Indy 10 的 SSH 协议栈对 SSH2 的支持非常浅,比如 KEXINIT 阶段只实现了有限的密钥交换算法,现代 OpenSSH 服务器普遍默认的 curve25519-sha256 它处理不了,连接就那么卡在协商阶段,不抛异常也不返回,活脱脱一个黑匣子。

其次是 SFTP 通道。Indy 的 TIdSFTP 连目录枚举都做得不够完整,文件大小、权限、修改时间这些 SFTP v3 的属性经常丢;一个文件传一半连接断了,也没有清晰的错误状态给你判断。我曾经接一个项目,前期用 Indy 写了半套文件同步逻辑,到联调阶段发现服务器根本握手不上,最后全部推翻换成 SecureBridge。如果你的业务要求是“能连通、能传文件、能排障”,Indy 自带的 SSH 栈只能算脚手架,够不到生产标准。

2.2 与 IPWorks、自封装方案的区别:组件化和完整协议栈是两回事

另一种常见做法是封装外部 plink.exe 或 ssh 命令行,靠解析 stdout 来拿到结果。好处是零安装,坏处一堆:无法拿到进度回调、多会话要起多个进程、密钥缓存和 passphrase 处理麻烦,Windows 的控制台编码还能让你在输出中文文件名时翻车。用下来你会发现这套工作不省事,最终还是要找一个进程内的协议实现。SecureBridge 的差别在于把 SSH 协议栈原生编进 Delphi 单元,连接、认证、通道、 SFTP 全部在你进程内完成,事件回调直接触发在 VCL 消息循环里(它也支持异步模式)。

还有 IPWorks SSH 这类跨语言产品,支持平台多,但对 Delphi 特定版本的跟进和打包体验未必有 Devart 这么同步。SecureBridge 和 Devart 自家的 SQL Server、MySQL 数据访问组件同系,命名风格一致:TScSSHClient、TScSFTP、TScSSHTunnel、TScSSHLog,用起来基本不突兀。如果你刚开始学 Delphi,想通过真实组件理解 SSH 握手流程,也可以去读它自带的 Ssh*.pas 源码头,那比看 RFC 好懂。顺带提一句,Lazarus 生态里也有类似选择,但你在 Delphi 13.1 下做生产系统,SecureBridge 的安装和升级路径明显更平滑。

2.3 隧道、证书与日志:专业版真正值钱的三件事

v11.0.1 Professional 和标准版、免费版拉开距离的不是“能不能连”,而是这三件事。第一是 SSH 隧道即端口转发。生产环境里最常见的是远程 MySQL 只监听 127.0.0.1,不允许外网直连,你用 TScSSHTunnel 把服务器的 3306 映射到本机 localhost:3306,数据库客户端直接连本地端口就能走 SSH 加密信道访问服务,不需要在防火墙上开 3306。同理,调试远程应用或访问内网 Web 服务也可以用这个思路。第二是证书管理。SecureBridge 能加载 OpenSSL 生成的 PEM 私钥,也能读 PuTTY 的 .ppk,并支持 Passphrase;密钥轮换时只需要改配置路径,不用重编译。第三是日志。连不上服务器时,TScSSHLog 可以把握手过程、认证结果、密钥协商细节写到文件,你不再靠猜排查。选型时如果只是临时传一次文件,标准版够用;如果是周期性任务、多环境部署、要定位线上问题,Professional 的隧道和日志这两项能回本。

3. 从 .7z 到 IDE 面板:SecureBridge v11.0.1 的完整安装步骤

先说一句止损的建议:如果你的 Delphi 是从 13.1 升到 13.2 这种小版本更新,SecureBridge 通常也能识别新版本,但最好先在旧版本上反激活,再在 13.2 里重装激活,这是免去注册表残留的后悔药。

3.1 解压 .7z 后的包结构:先分清编译期与运行期文件

解压这个 .7z 后,你会看到安装程序和若干子目录,一般命名里会区分 x86、x64 平台。这里有个容易翻车的点:Delphi 13.1 的 IDE 本身是 64 位的,但 SecureBridge 运行库同时提供 32 位和 64 位版本,因为同一个 IDE 可以编译出 32 位和 64 位的目标程序。装的时候别只看 IDE 位数,还要看你后续要部署的目标平台。用 7-Zip 解压到一个固定目录,比如 D:\Components\SecureBridge,不要散落到 Delphi 安装目录里。安装前关闭 Delphi 和其他使用 bpl 的程序,否则安装程序写注册表时可能遇到文件占用。如果安装程序检测不到 Delphi 13.1(非默认安装路径时会这样),手动指定 IDE 根目录,通常就是 Program Files 下的 Embarcadero 目录,安装日志里会写出它最终找到的 Delphi 版本号。

安装程序默认会探测系统已安装的 RAD Studio 版本并要求选择目标 IDE。确认勾选了 Delphi 13.1 后,下一步会让你挑选组件:一般默认全选即可。这里值得一提的是源码与 DCU 的区别:普通安装包会带上编译好的 DCU 和运行时 bpl,写代码时足够;若你以后想跟踪 SecureBridge 内部行为,Professional 通常带源码,源码版安装后需要在 IDE 里手动编译 dcl 包,耗时多一些但可控性强。

3.2 源码安装:Library Path 与 Tool Palette 的配置顺序

无论你用的是安装版还是源码版,装完第一步不是急着写代码,而是检查两个路径:IDE 的 Library Path 和工程的 Search Path。前者让 IDE 在设计期认识这些单元并显示组件,后者让编译期能找到 DCU/PAS。很多“装成功了但编译报 SshClient.dcu not found”的情况,都是因为这一步没做。操作顺序我一般这样走:

打开 Tools > Options > IDE > Library,把 SecureBridge 的 Source 目录加入 Library Path;如果你的编译目标包含 Win64,还要确认 Win64 的 DCU 输出目录也被包含。随后打开 Component > Install Packages,点击 Add,选择安装目录里以 dcl 开头的设计期包文件,确定后工具面板会出现“SecureBridge”这一页。如果这一页空无一物,多半是你 Add 的 bpl 和你当前 IDE 平台不匹配——64 位 IDE 必须加载 64 位设计包。

最后验证:新建一个 VCL 工程,从组件面板拖一个 TScSSHClient 到窗体,按 F9 编译。能过,说明库路径没问题。若报 File not found 错误,回到上一步重新核对路径。这里要提醒:有些选手图省事直接把目录加到系统 PATH,那对 IDE 无用,必须在 Library 里配置。

3.3 激活与版本验证:注册码不是填完就结束

SecureBridge Professional 安装完成后需要激活。启动 Delphi 后,第一次在设计期使用控件时会弹激活对话框,填入授权序列号后,它会在注册表写入许可信息。如果激活失败,表现很刁钻:编译能通过,但程序一运行、创建 TScSSHClient 实例时就抛异常,提示包含 “License” 字样。遇到这种情况,先别急着重装,按三个顺序排查:第一,确认 Delphi 是否以管理员权限运行,激活写注册表很容易受 UAC 影响;第二,检查系统时间是否准确,激活服务对时间偏移比较敏感;第三,若你之前在多台机器装过,确认反激活已经在旧机器上做完,激活次数用完会直接拒绝新机激活。

激活成功后,你可以拖入一个 TScSSHClient,在设计器里双击打开连接编辑器,能看到 Host、Port、UserName、Password 等属性,说明设计期状态正常。到这里 SecureBridge v11.0.1 Professional 才算真正接入了 Delphi 13.1,可以开始干活了。

4. 最小复现:用 TScSSHClient 跑通 SSH + SFTP 上传

代码部分。直接在一个按钮的 Click 事件里写,先用密码认证把 SSH 握手跑通,这是最基础的验证。

4.1 最小连接:密码认证跑通 SSH 握手

procedure TForm1.BtnConnectClick(Sender: TObject); var Client: TScSSHClient; begin Client := TScSSHClient.Create(nil); try Client.HostName := '192.168.1.10'; Client.Port := 22; Client.UserName := 'root'; Client.Authentication := atPassword; Client.Password := '你的密码'; Client.Timeout := 10; // 10 秒内连不上就抛出异常 Client.Connect; // 连接成功后打印服务器版本,顺便验证会话真实可用 ShowMessage(Client.ServerVersion); finally Client.Free; end; end;

代码逻辑很直接:创建客户端对象,填主机、端口、用户名、认证方式,再调用 Connect 阻塞执行。Connect 返回意味着 SSH 握手、密钥交换、用户认证全部完成,此时 ServerVersion 属性会带上远程服务器的软件版本,比如 OpenSSH_8.9p1,这行信息在排障时很有用。

这里有两个关键参数。第一个是 Authentication,它决定走密码还是公钥流程;如果服务器只接受公钥,你在密码认证阶段就会收到异常,日志里会写认证方式不匹配。第二个是 Timeout,单位秒,默认值可能为 0 即无限等待,我建议生产代码显式设置,10 到 30 秒都行,避免网络黑洞里永久阻塞。同步 Connect 在 VCL 主线程里会让界面冻结,真实项目建议用 TTask 包一层,或者启用 Client 的异步模式,后面会展开。

4.2 公钥认证与 .ppk 格式转换

密码认证只适合临时联调,自动化任务要换公钥。SecureBridge 对 OpenSSL PEM 格式的支持要看版本,而 v11.0.1 这类专业版处理较新的 OPENSSH PRIVATE KEY 时也并非总是顺利。我最常用的做法是先用 PuTTYgen 做一次格式转换:打开 PuTTYgen,File > Load 载入 OpenSSL 生成的私钥,输入原 passphrase,然后 Save private key 存成 .ppk 文件。转好后在代码里这样写:

Client.Authentication := atPublicKey; Client.PrivateKeyFile := 'C:\keys\deploy_key.ppk'; Client.KeyPassphrase := '私钥口令'; // 没设置就留空字符串 Client.Connect;

逻辑上,SecureBridge 从 PrivateKeyFile 读取密钥材料,用 KeyPassphrase 解密出私钥,再参与公钥认证;公钥由私钥推导,不需要你显式传公钥文件,服务器端只要把对应公钥放进 authorized_keys 即可。这里有一个常见误会:代码里同时填了 Password 和 PrivateKeyFile,认证结果只取决于 Authentication 当前值,不会自动做密码优先、密钥兜底的流程。若你想要回退,得自己 catch 异常后换认证方式重新连。另一个注意点是私钥文件路径不要放在网盘或共享目录,文件锁会影响读取,本地副本是最稳的。

4.3 SFTP 上传下载的 3 个关键参数

连接建立后,传文件用 TScSFTP,它必须挂在同一个 SSH 会话上,避免重复握手。

var SFTP: TScSFTP; begin SFTP := TScSFTP.Create(nil); try SFTP.SSH := Client; // 复用 4.1 的 Client 连接 SFTP.Connect; SFTP.Timeout := 30; // 单次 SFTP 操作超时 SFTP.OverwriteMode := omOverwrite; // 覆盖远程同名文件 SFTP.Put('C:\tmp\report.pdf', '/home/user/report.pdf'); SFTP.Get('/home/user/backup.zip', 'C:\tmp\backup.zip'); SFTP.Disconnect; finally SFTP.Free; end; end;

第一个关键参数是 Timeout。SFTP 的每个底层请求都受它控制,网络抖动时如果保持默认无限等待,任务就会卡死。我的习惯是 SSH 层超时设 10 秒,SFTP 层超时设 30 秒,两者错开,既不互相干扰,又能快速暴露问题。第二个是 OverwriteMode,决定远程存在同名文件时是报错、覆盖还是追加;定时任务建议显式指定覆盖,否则文件冲突会让任务静默失败,日志里啥也没有。第三个是 Compression,适合大文件或慢链路,压缩开启后传输量明显减少,代价是 CPU 占用升高,目标服务器负载高时慎用。想观察传输进度,可以挂 OnProgress 事件,在事件里更新 UI 进度条。Put/Get 是同步阻塞调用,放在 UI 线程会卡界面,我会用 TThread 或 TTask 把整个 SFTP 会话丢到后台,界面只接收进度回调。

4.4 顺手封装一个执行远程命令的通道

除了传文件,SecureBridge 的 TScSSHChannel 可以在同一会话上执行远程命令。举一个高频场景:SFTP 上传之前先远程建目录,避免 Put 到不存在路径时报错。

var Ch: TScSSHChannel; Output: string; begin Ch := TScSSHChannel.Create(nil); try Ch.SSH := Client; // 复用同一 SSH 会话 Ch.ChannelType := ctSession; Ch.Connect; Ch.WriteString('mkdir -p /home/user/data'#10); Output := Ch.ReadString; // 读取命令输出,便于确认结果 Ch.Disconnect; finally Ch.Free; end; end;

这段代码和 SFTP 的复用关系很关键:TScSSHChannel 和 TScSFTP 共享一个 TScSSHClient 的底层连接,不会多一次握手,也不会多一个会话。ChannelType 指定为 ctSession 表示这是一条普通执行命令的会话通道;写命令时记得在末尾加换行符,这是 shell 识别命令结束的标志。ReadString 会阻塞到有输出返回,如果命令本身耗时长,注意同样受 Timeout 约束。用这个通道可以串起“建目录、传文件、执行后续脚本”的完整自动化,不用再额外拉起 SSH 进程。

5. 避坑:SecureBridge 在 Delphi 13.1 下最容易翻车的 5 个地方

5.1 现象 1:拖控件后编译报 DCU not found

现象是组件面板里看得到 TScSSHClient,拖到窗体也没问题,一编译就报 File not found: SshClient.dcu。

原因基本都是 Delphi 的 Library Path 只覆盖了运行时包输出目录,而你在代码里直接 uses 了 SshClient 单元,搜索路径里却没有包含 SecureBridge 的源码目录。

解决:打开 Tools > Options > IDE > Library,把 SecureBridge 的 Source 目录加进去;同时在 Project > Options > Delphi Compiler > Search Path 再添加一次,保存后完整 Build。如果依然报错,去确认当前活动目标平台和你安装的运行库位数一致,32 位工程去引 64 位 DCU 同样会报这个错。

5.2 现象 2:连接超时像黑匣子一样卡死

现象是 Connect 调用后界面失去响应,迟迟不返回;TScSSHLog 没有写出任何有效信息。

原因多半是 Timeout 默认无限等待,SecureBridge 在首包丢失时不会主动中断,只能等系统 TCP 超时,那段时间可能长达几分钟,期间 UI 完全冻结。

解决:连接前显式设置 Client.Timeout := 10,对 Connect 包一层 try/except,异常消息里通常能看到具体原因。同时把 TScSSHLog 挂上,日志级别设置到最详细那一档,复现一次后看日志停在哪个阶段——是 DNS 解析、TCP 建连还是密钥交换。这一步做完,超时就不再是黑匣子了。

5.3 现象 3:密钥连不上,密码却能连

现象:同一个服务器,密码认证正常,换成公钥认证后报错或直接被断开。

原因有三层,按出现频率排:第一,私钥格式不兼容,OpenSSL 新的 OPENSSH PRIVATE KEY 格式在部分版本里识别不完整;第二,私钥文件路径错误或没有读取权限;第三,服务器端 authorized_keys 里存放的公钥与客户端私钥不匹配,OpenSSH 在公钥无法验证时会直接拒绝,而不会告知你具体原因。

解决:先用 PuTTYgen 把 OpenSSL 私钥导入另存为 .ppk,然后确认 PrivateKeyFile 指向的是文件而不是目录;如果有 Passphrase 必须显式赋给 KeyPassphrase,SecureBridge 不会弹框问你。服务器端排查时,去看 /var/log/auth.log 里有没有 “Authentication refused” 字样,能区分是密钥无效还是客户端根本没发过来。

5.4 现象 4:SFTP 传大文件时中途断开

现象:小文件传输一切正常,传 300MB 以上的文件时进度条走到一半,提示连接断开。

原因:网络路径中的防火墙或设备会把空闲的 TCP 连接掐掉。SecureBridge 传输大文件时,如果中间有较长的沉默期,会话保活没启用,连接就被中间设备回收了。

解决:在 TScSSHClient 上设置一个合理的 KeepAliveInterval,常见做法是 15 秒左右;同时把 SFTP.Timeout 稍微放大,但 SSH 层 Timeout 不要跟着放大,两层职责不同,一个是会话保活,一个是单次操作容忍。另外,SFTP 中断后默认不支持续传,我一般先把文件下载到临时文件名,传完再改名,这样即使中断,目标目录里也不会出现半截文件被其他程序误用。

5.5 现象 5:32 位编译正常,切到 64 位运行崩溃

现象:32 位 Debug 跑得好好的,切到 64 位目标平台运行,一创建 TScSSHClient 就访问违例。

原因:安装时没有选择安装 64 位运行库,或者 Library Path 里只配了 32 位 DCU,64 位编译时链接了错误位数的单元。

解决:重新运行安装程序,确认勾选了 x64 相关组件;查看 IDE Library 设置中 Win64 的 DCU 输出目录是否在搜索路径内;最后打开 Project Manager,确认当前活动平台是 64 位,然后执行一次 Clean 再 Build。验证方法是直接用 Process Explorer 查看进程加载的 dll/bpl,路径应指向 x64 子目录,而不是 x86。

6. 把隧道和私钥匹配封装成自己的工具函数

SecureBridge 装好、代码跑通,不等于这事就完了。最后分享两个我长期沉淀在自己公共单元里的工具函数,一个是私钥自动匹配,一个是隧道封装。

私钥自动匹配主要用于密钥轮换期。团队里总有人把新私钥放到服务器上但本地还没同步,或者反之,与其每次手工试,不如写一个函数:

function TryConnectWithKeys( const AHost: string; APort: Integer; const AUser: string; const AKeys: array of string; var AClient: TScSSHClient): Boolean; var I: Integer; begin Result := False; AClient := nil; for I := 0 to High(AKeys) do begin AClient := TScSSHClient.Create(nil); try AClient.HostName := AHost; AClient.Port := APort; AClient.UserName := AUser; AClient.Authentication := atPublicKey; AClient.PrivateKeyFile := AKeys[I]; AClient.Timeout := 15; AClient.Connect; Result := True; Exit; // 连接成功,AClient 交还给调用方 except AClient.Free; // 失败必须释放本次实例 AClient := nil; end; end; end;

调用时把多组私钥路径传进去,谁先握手成功就用谁;失败的一方在循环内释放掉,避免内存泄漏。这个函数帮我省掉了好几次深夜加班。

隧道封装更实用。把 TScSSHTunnel 和 SSH 客户端绑定,把远程的 MySQL 3306 转发到本地,然后数据库工具直连 127.0.0.1:3306 就能访问内网数据库。封装时注意两点:LocalPort 不要占用系统已监听端口,RemoteHost 在隧道模式下指向服务器视角的主机名,多半是 127.0.0.1。停隧道时先 Active := False,再断开 SSH 会话,这个顺序我反着操作过一次,结果 Windows 上端口句柄被占用,清理起来相当麻烦。

我自己现在用 SecureBridge 养成了一个固定习惯:任何 SSH 客户端强制设 Timeout,连接成功后先读 ServerVersion 并写进日志;所有私钥统一转成 .ppk,同时保留一份 OpenSSL 原始 PEM 作为备份;隧道和连接函数固定在公共单元里,不再散落在业务工程中。这套习惯帮我减少了很多重复排障,也希望帮到你减少踩坑的时间。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询