繁体   English   中英

Delphi Indy验证服务器证书SSL

[英]Delphi Indy verify server certificate SSL

我已经浏览了互联网,但在使用TIdHTTP通过HTTPS连接时,没有找到关于如何验证证书的解决方案或方法。

我已经将IdSSLIOHandlerSocketOpenSSL组件连接为IOHandler,设置SSLModes等,但是当我浏览到https://s3.amazonaws.com时,它无法验证证书。

OpenSSL(Indy)给出

“使用SSL连接时出错.SSL3_GET_SERVER_CERTIFICATE:证书验证失败”

已成功加载OpenSSL库(使用WhichFailedToLoad进行检查)。 OnStatusInfo事​​件写入以下内容:

SSL状态:“在/初始化之前”

SSL状态:“在/初始化之前”

SSL状态:“SSLv2 / v3写客户端问候A”

SSL状态:“SSLv3读取服务器问候A”

SSL状态:“SSLv3读取服务器证书B”

SSL状态:“SSLv3读取服务器证书B”

SSL状态:“SSLv3读取服务器证书B”

并且OnVerifyPeer,AOk = False。

我怎样才能让它正确验证。 这是怎么回事?

感谢阅读,阿德里安

您必须为TIdSSLIOHandlerSocketOpenSSL组件的OnVerifyPeer事件实现事件处理程序。

来自IdSSLOpenSSL.pas:

请注意,您确实应该始终实现OnVerifyPeer,否则不会检查您要连接的对等方的证书以确保它是有效的。

如果您只想考虑库认为有效的相同证书,您只需要以这种方式实现它:

function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509;
  AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
  Result := AOk;
end;

因为Indy首先检查证书的有效性,如果在AOk参数中是否正常则通过。 最后一个词是在你的代码中,因为你可能想要传递某些类型的小验证错误 ,比如过时,或者甚至询问用户是否接受证书是否有任何错误(次要或不是) 。

要了解它为何如此工作,您可能还想阅读IdSSLOpenSSL.pas文件顶部的所有注释:

{

有关OnVerifyPeer的重要信息:2005年2月的Rev 1.39故意破坏了OnVerifyPeer接口,这显然只会影响作为SSL协商的一部分实现该回调的程序。 请注意,您确实应该始终实现OnVerifyPeer,否则不会检查您要连接的对等方的证书以确保它是有效的。

在此之前,如果SSL库检测到证书有问题或者深度不足(即VerifyCallback中的“Ok”参数为0 / FALSE),则无论您的OnVerifyPeer是返回True还是False,SSL连接都将是故意失败了。

这就产生了一个问题,即使链中的一个证书(证书链中的每个证书都调用一次OnVerifyPeer)只有一个非常小的问题,用户可能乐于接受,SSL协商会失败的。 但是,当用户为OnVerifyPeer返回True时,更改代码以允许SSL连接将意味着依赖于自动拒绝无效证书的现有代码将接受无效证书,这将是不可接受的安全性更改。

因此,OnVerifyPeer被更改为通过添加AOk参数故意破坏现有代码。 要保留以前的功能,OnVerifyPeer事件应该执行“Result:= AOk;”。 如果您希望考虑接受SSL库认为无效的证书,那么在您的OnVerifyPeer中,确保您确信证书确实有效,然后将Result设置为True。 实际上,除了检查AOk之外,您应该始终实现代码,以确保您只接受有效的证书(至少从您的角度来看)。

Ciatel Costelloe,ccostelloe [_a_t_] flogas.ie

}

{

RLebeau 2011年1月12日:再次打破OnVerifyPeer事件,这次添加一个额外的AError参数(补丁由“jvlad”提供,dmda @ yandex.ru)。 这有助于用户代码区分自签名证书和无效证书。

}

我知道这是一个古老的帖子,但我能找到解决问题的全部内容。 所以我想在其他人遇到同样问题时添加Marcus的答案:当OpenSSL在PC上找不到根证书时,AError将返回#19(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN),并且根证书的AOK将为false。 当您从文件手动加载根证书时,AOK应该始终返回true(并且您已经实现了某种类型的证书固定):

FSSLIOHandlerSocketOpenSSL.SSLOptions.RootCertFile:='MyRoot.cer';

如果您收到类似SSL3_GET_SERVER_CERTIFICATE:certificate verify failed的错误SSL3_GET_SERVER_CERTIFICATE:certificate verify failed ,请继续阅读:

在Indy 10中,如果将VerifyDepth设置为0 ,则0实际上意味着all

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM