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 实施)。
我有一个用 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 实施)。