Delphi7中TidTCPServer/TidTCPClient添加SSL加密握手失败求助
解决SSL握手失败(sslv3 alert handshake failure)的方案
针对你遇到的问题,结合Indy10+OpenSSL1.0.2在Delphi7中的配置,以下是具体的修复步骤:
1. 服务端必须配置SSL证书(核心问题)
SSL/TLS握手要求服务端提供证书,哪怕是自签名证书,否则OpenSSL会直接拒绝握手。你之前用TIdHTTP可能隐式处理了证书,但自定义TCP服务端需要手动配置:
生成自签名证书
用OpenSSL命令行生成(确保已安装OpenSSL):
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes
将生成的server.key和server.crt放到服务端程序的运行目录。
服务端加载证书
在服务端Form的OnCreate事件中添加代码:
procedure TVTServerForm.FormCreate(Sender: TObject); begin SSLHandler.SSLOptions.CertFile := ExtractFilePath(Application.ExeName) + 'server.crt'; SSLHandler.SSLOptions.KeyFile := ExtractFilePath(Application.ExeName) + 'server.key'; end;
2. 客户端信任自签名证书
因为是自签名证书,客户端需要跳过证书验证(仅测试环境使用,正式环境需做证书校验):
添加OnVerifyPeer事件处理
在客户端Form中给SSLHandler添加OnVerifyPeer事件,并实现:
procedure TMainForm.SSLHandlerVerifyPeer(Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer; var AAccept: Boolean); begin AAccept := True; // 信任所有证书,测试用 end;
3. 调整SSL握手触发时机
客户端在OnConnected中设置PassThrough := False后,建议手动触发SSL握手,避免发送数据时握手未完成:
procedure TMainForm.TCPClientConnected(Sender: TObject); var Ret: string; begin with TIdSSLIOHandlerSocketBase(TCPClient.IOHandler) do begin Passthrough := False; StartSSL; // 手动启动SSL握手 end; TCPClient.IOHandler.Writeln('Login'); Ret := TCPClient.IOHandler.ReadLn; // ...后续逻辑 end;
4. 修复服务端监听绑定
你的服务端DFM中Bindings = <>,这可能导致服务端未正确监听端口,添加绑定配置:
procedure TVTServerForm.FormCreate(Sender: TObject); begin // ...之前的证书加载代码 TCPServer.Bindings.Clear; TCPServer.Bindings.Add.SetBinding('0.0.0.0', 2323); // 监听所有IP的2323端口 end;
5. 验证OpenSSL DLL兼容性
确保使用32位版本的libeay32.dll和ssleay32.dll(Delphi7为32位编译器),版本为OpenSSL 1.0.2的稳定版(如1.0.2u),并放到客户端和服务端的运行目录。
完成以上配置后,重新编译测试,SSL握手失败的问题应该可以解决。
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

