php sslv3握手失败,关于ssl:sslv3警报握手失败Delphi Indy

我一直在使用:

德尔福XE8

Indy版本10.6.2.5263

预编译的打开SSL dll文件(Win 32位)v1.0.2.l

将Method设置为sslvSSLv23的TIdSSLIOHandlerSocketOpenSSL

向服务器提交POST请求。几个月来,它一直像魅力一样运作。

突然,出现了一个疯狂的错误:

14094410 sslv3警报握手失败。

一位同事通过强制使用TLS 1.2,正在使用SOAP UI向同一服务器提交请求,并且该方法有效。我尝试将TIdSSLIOHandlerSocketOpenSSL1方法设置为sslvTLSv1_2,并将模式更改为sslmClient,但是结果始终相同。

我认为通过将Method设置为sslvTLSv1_2,就不可能收到与SSLv3相关的错误。

我检查了这些stackoverflow帖子:

Indy 10和sslvTLSv1_2

如何使Indy OpenSSL与大多数服务器兼容

和其他一些线程,但我无法找到此问题的根本原因。

也许我缺少了一些东西。你能给我一个提示吗?

TLS是SSL 3.0的扩展,并且OpenSSL使用SSLv3功能来实现TLS,这就是警报显示SSLv3的原因。但是,如果没有有关警报实际含义的具体细节,尤其是警报编号,就无法知道OpenSSL为什么会失败。另外,您的Indy有点旧,当前版本是10.6.2.5432,您应该考虑升级,以便拥有最新的OpenSSL支持代码。

您好雷米,确切的错误是:错误:14094410:SSL例程:ssl3_read_bytes:sslv3警报握手失败。我将尝试获取最新的Indy版本,然后重试。

嗨,我已经更新了Indy组件,但是现在显示的版本是10.6.2.0。

您是直接从SVN下载,还是从Fulgan下载了每晚zip?邮政编码具有正确的版本号。

您好雷米,我已经直接通过SVN下载了我的第一个Indy升级。它显示了版本10.6.2.0。发表您的评论后,我已经下载了最新的Fulgran zip(Indy10_5432.z??ip)。卸载SVN Indy,然后完成Fulgran zip Indy的全新安装。该版本还显示10.6.2.0,错误:14094410:SSL例程:ssl3_read_bytes:sslv3警报握手失败仍然存在。

Fulgan zip中应该有正确的版本号(请参见IdVers.inc),它应该是10.6.2.5432,与zip文件名相同,而不是10.6.2.0。无论如何,您都会收到一般性警报失败,因此很难诊断原因。服务器拒绝您的TLS握手,而没有通过更具体的警报真正解释其原因。尝试与其他库(例如libCURL)甚至OpenSSL自己的s_client连接,并使用数据包嗅探器(例如Wireshark)来比较握手。

您好雷米,我用Wireshark和一些Java代码做了一些测试。 Wireshark透露,Indy组件始终发送TLSv1请求-无论我通过SSLOptions.Method还是SSLOptions.SSLVersions选择什么。 Java代码请求使用TLSv1.2,请求成功。所以我的问题是,indy组件始终发送TLSv1

Indy不是发送握手的人,OpenSSL是。使用的版本取决于Indys SSLOptions的配置方式。如果仅将其设置为sslvTLSv1_2,则除非您使用的是禁用了TLS 1.2的OpenSSL DLL,否则它应该发送TLS 1.2问候。在这种情况下,Indy将回退到TLS1.0。IndysIsOpenSSL_TLSv1_2_Available()函数是否返回true或false(将OpenSSL加载到内存后)?

您好雷米,IsOpenSSL_TLSv1_2_Available()在我提交请求后显示TRUE。

遇到了同样的问题,下面的源代码很有吸引力。 我从该站点复制了此代码,但找不到指向原始答案的链接。 请注意,源代码不是我的。

TCustomIdHTTP = class(TIdHTTP)

public

constructor Create(AOwner: TComponent);

private

procedure OnStatusInfoEx(ASender: TObject; const AsslSocket: PSSL; const AWhere, Aret: TIdC_INT; const AType, AMsg: String);

end;

constructor TCustomIdHTTP.Create(AOwner: TComponent);

begin

IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);

with IOHandler as TIdSSLIOHandlerSocketOpenSSL do

begin

OnStatusInfoEx := Self.OnStatusInfoEx;

SSLOptions.Method := sslvSSLv23;

SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];

end;

inherited Create(AOwner);

end;

procedure TCustomIdHTTP.OnStatusInfoEx(ASender: TObject; const AsslSocket: PSSL;

const AWhere, Aret: TIdC_INT; const AType, AMsg: String);

begin

SSL_set_tlsext_host_name(AsslSocket, Request.Host);

end;

请注意,您在使用中需要IdCTypes和IdSSLOpenSSLHeaders(我必须对此进行挖掘)

确保您的应用程序文件夹中有最新的libeay32.dll和ssleay32.dll

以前-我尝试了您发布的解决方案,效果很好

我自己在某些网站上也遇到过同样的问题。 我已经通过使用TRESTClient而不是TIdHTTP和OpenSSL解决了它。

TRESTClient

TRESTRequest

TRESTResponse

您可以在Delphi IDE的"工具"菜单中的" REST调试器"中设置URL,身份验证和参数,然后将组件复制到剪贴板中,以带头学习。

起初这是我的解决方案,除了然后是获取二进制数据的部分,在这种情况下,TRESTClient不知道如何处理二进制数据...

你可能感兴趣的:(php,sslv3握手失败)