我有一个使用 XE2 开发的 Windows 桌面应用程序,它以 JSON 格式从远程服务器中提取数据。我使用 Indy 10 来管理它。
应用程序运行良好,直到我收到服务器提供商人员的电子邮件:
“...确保通信安全的唯一协议(protocol)将是 TLS 1.2。旧版本(TLS.1.0、TLS.1.1 或 SSLv3)将不再有效。” 他们建议使用 TLS 1.2 或更高版本。
从那以后我有以下运行时错误
First chance exception at $7518845D. 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 $7518845D. 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,因此您必须更改代码以始终无条件地创建 TIdSSLIOHandlerSocketOpenSSL
,以便启用 TLS v1.2,无论使用的编译器版本(至少在实现 this ticket 之前)。
关于delphi - TIdSSLIOHandlerSocketOpenSSL 和 TLS 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54775877/