Delphi Indy验证服务器证书SSL

Adr*_*ian 7 delphi ssl indy

我已经浏览了互联网,但在使用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.

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

感谢阅读,阿德里安

jac*_*ate 10

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

来自IdSSLOpenSSL.pas:

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

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

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

因为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).这有助于用户代码区分自签名证书和无效证书.

}