TIdSSLIOHandlerSocketOpenSSL 和 TLS 协议

TIdSSLIOHandlerSocketOpenSSL and TLS protocol

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

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

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

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

First chance exception at 18845D. Exception class EIdOSSLUnderlyingCryptoError with message 'Error connecting with SSL. Error connecting with SSL. error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number'.

我发现调用 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;

但现在我有另一个错误:

First chance exception at 18845D. Exception class EIdSocketError with message 'Socket Error # 10054 Connection reset by peer.'.

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

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

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

FIdSSL.SSLOptions.Method := sslvTLSv1_2;

或:

FIdSSL.SSLOptions.SSLVersions := [sslvTLSv1_2];

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

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

此外,您需要从代码中删除 {$IFDEF VER230}。这限制了您的代码仅在专门针对 XE2 进行编译时才创建 TIdSSLIOHandlerSocketOpenSSL。默认情况下,TIdSSLIOHandlerSocketOpenSSL 仅启用 TLS v1.0,因此无论使用何种编译器版本(至少直到 this ticket 实施)。