Delphi11.2中如何为TIdFTP启用数据连接TLS会话恢复?
解决TIdFTP显式TLS传输时数据连接TLS会话恢复失败的问题
问题场景
使用Embarcadero® RAD Studio 11(Delphi 11.2,版本28.0.46141.0937)自带的Indy 10.6.2.0组件,配置TIdFTP实现显式TLS传输,执行Put操作时弹出错误:
Unable to build data connection: TLS session of data connection not resumed.
FileZilla Server 1.6.7日志同步显示:
[Error] TLS session of data connection not resumed.
解决方法
Indy 10.6.2.0默认未启用TLS会话恢复,需通过以下配置修改实现:
1. 启用SSL会话缓存并设置缓存模式
为TIdSSLIOHandlerSocketOpenSSL开启会话缓存,并设置缓存模式为服务器端模式,确保客户端能复用控制连接的TLS会话。
2. 传递控制连接的会话ID到数据连接
在控制连接完成TLS握手后,将控制连接的会话ID赋值给SSL选项的SessionID,后续数据连接会自动使用该ID恢复会话。
修改后的完整代码
implementation uses IdFTP, IdSSLOpenSSL, IdExplicitTLSClientServerBase, IdFTPCommon; procedure DoSomething; var ftp: TIdFTP; ssl: TIdSSLIOHandlerSocketOpenSSL; begin ftp := TIdFTP.Create; try ssl := TIdSSLIOHandlerSocketOpenSSL.Create(ftp); ssl.SSLOptions.SSLVersions := [sslvTLSv1_2]; // 启用SSL会话缓存并设置模式 ssl.SSLOptions.SessionCache := True; ssl.SSLOptions.SessionCacheMode := scmServer; ftp.IOHandler := ssl; ftp.Host := 'myhost'; ftp.Port := 21; ftp.Username := 'myuser'; ftp.Password := 'mytopsecretpassword'; ftp.Passive := true; ftp.UseTLS := utUseExplicitTLS; ftp.AUTHCmd := tAuthTLS; ftp.DataPortProtection := ftpdpsPrivate; ftp.Connect; if ftp.Connected then begin // 将控制连接的TLS会话ID传递给后续数据连接 ssl.SSLOptions.SessionID := ssl.SessionID; ftp.Put('C:\temp\test1.dat', 'test1.dat'); ftp.Put('C:\temp\test2.dat', 'test2.dat'); end; ftp.Disconnect; finally ftp.Free; end; end;
关键修改说明
ssl.SSLOptions.SessionCache := True;:开启SSL会话缓存功能,允许复用已建立的TLS会话ssl.SSLOptions.SessionCacheMode := scmServer;:设置缓存模式为服务器端,客户端会自动向服务器请求复用会话ssl.SSLOptions.SessionID := ssl.SessionID;:在控制连接建立后,将当前会话ID保存,确保后续数据连接使用同一个会话ID进行恢复
内容的提问来源于stack exchange,提问作者complete_stranger
相关产品推荐
相关产品推荐

