TIdSSLIOHandlerSocketOpenSSL 和 TLS 协议

pio*_*pio 2 delphi ssl indy

我有一个在 XE2 中开发的 Windows 桌面应用程序,它以 JSON 格式从远程服务器中提取数据。我使用 Indy 10 来管理这个。

该应用程序运行良好,直到我收到服务器提供商人员的电子邮件:

“......保护通信安全的唯一协议将是 TLS 1.2。旧版本(TLS.1.0、TLS.1.1 或 SSLv3)将不再有效。” 他们建议使用 TLS 1.2 或更高版本。

从那时起我有以下运行时错误

第一次机会例外,价格为 $7518845D。异常类 EIdOSSLUnderlyingCryptoError 带有消息“连接 SSL 时出错”。使用 SSL 连接时出错。错误:1408F10B:SSL 例程:SSL3_GET_RECORD:版本号错误。

我发现在调用 FidHTTP.Post 时触发了错误(FidHTTP 是 TidHTTP 的一个实例)。

我已按以下方式修改了创建类的方法:

constructor TMyClass.Create;

begin
  FidHTTP := TidHTTP.Create(nil);
  FidHTTP.HTTPOptions := FidHTTP.HTTPOptions - [hoForceEncodeParams];
  FidHTTP.Intercept := TIdLogFile.Create(FidHTTP);

  TIdLogFile(FidHTTP.Intercept).Filename := 'c:\'+s+'.log';
  TIdLogFile(FidHTTP.Intercept).Active := true;
  {$IFDEF VER230}
  FIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create;
  FIdSSL.SSLOptions.Method:=sslvTLSv1; // I have added this line
  {$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)

但现在我有另一个错误:

第一次机会例外,价格为 $7518845D。异常类 EIdSocketError 带有消息“套接字错误 #10054 对等方重置连接。”。

我用谷歌搜索过这个,但我只找到了有关 FTP 的信息,这不是我的情况。

我究竟做错了什么?是因为我有一个没有 sslvTLSv1_2 选项的旧版 Indy 还是?

Rem*_*eau 5

sslvTLSv1仅适用于 TLS v1.0。要使用 TLS v1.2,您需要sslvTLSv1_2改用:

FIdSSL.SSLOptions.Method := sslvTLSv1_2;
Run Code Online (Sandbox Code Playgroud)

或者:

FIdSSL.SSLOptions.SSLVersions := [sslvTLSv1_2];
Run Code Online (Sandbox Code Playgroud)

如果您的 Indy 版本没有,sslvTLSv1_2那么您将不得不升级。Indy 的当前版本是 v10.6.2.5494。

此外,请确保您至少使用 OpenSSL v1.0.1,这是首先添加对 TLS v1.2 支持的版本。Indy 10 支持的最新 OpenSSL 版本是 v1.0.2。

此外,您需要{$IFDEF VER230}从代码中删除。这限制了您的代码TIdSSLIOHandlerSocketOpenSSL只能在专门为 XE2 编译时创建。默认情况下,TIdSSLIOHandlerSocketOpenSSL仅启用 TLS v1.0,因此您必须更改代码以始终TIdSSLIOHandlerSocketOpenSSL无条件地创建TLS v1.2,无论使用的编译器版本如何(至少在实现此票证之前)。