Delphi - 与Indy组件的SSL TCP通信

时间:2012-08-07 11:08:40

标签: delphi ssl tcp openssl indy

我正在使用Delphi XE2中的TIdSSLIOHandlerSocketOpenSSL Indy组件通过TCP将数据发送到SSL服务器(Apple推送通知服务)。我已经让它在某种程度上工作,但不确定我是否会以最好的方式去做。我正在做以下事情:

  • 设置SSL属性inc。证书路径
  • 调用.Open方法打开连接
  • 检查OnStatusInfoEx事件中的AType参数,直到我收到“Handshake Done”
  • 使用.WriteDirect
  • 发送数据
  • 使用.Close
  • 关闭连接

有没有更好的方法来了解连接何时准备好发送数据?有没有人直接通过TCP使用TIdSSLIOHandlerSocketOpenSSL组件的示例代码?我发现的样本主要用于HTTP调用,其中仅附加TIdSSLIOHandlerSocketOpenSSL组件以保护连接。

2 个答案:

答案 0 :(得分:3)

由于您使用的是客户端组件,因此如果服务器要验证客户端的证书,则只需在客户端上设置证书。

否则,将TIdSSLIOHandlerSocketOpenSSL的SSLOptions.Mode设置为sslmClient,您应该可以连接。

最好启用VerifyMode并在套接字组件上使用OnVerifyPeer事件来验证服务器证书上的指纹,以避免人员受到中间攻击。

根据您的Indy版本,您可能需要将SSLOptions方法设置为sslvTLSv1。某些Web服务器不再支持版本9默认为的SSLv2。

以下是一些示例代码,演示了如何使用TCP组件通过SSL检索网页:

procedure TForm1.Button1Click(Sender: TObject);
var
  s: String;
begin
  IdTCPClient1.Host := 'example.com';
  IdTCPClient1.Port := 443;
  IdTCPClient1.Connect;
  IdTCPClient1.WriteLn('GET / HTTP/1.1');
  IdTCPClient1.WriteLn('Host: example.com');
  IdTCPClient1.WriteLn('');
  // Retrieve all the data until the server closes the connection
  s := IdTCPClient1.AllData;
  Memo1.Lines.Add(s);
end;

不要忘记将OpenSSL库libeay32.sllssleay32.dll包含在与Windows上的EXE相同的文件夹中。使用Indy 10的标准(最新)二进制文件。

答案 1 :(得分:0)

这对我有用。我正在使用Delphi 2010,但它可能在Delphi XE2(未经测试)上也能正常工作。我使用Indy的当前最新修订版,即版本4774,而不是开箱即用的版本。

我在数据模块或webmodule上有3个组件:

  1. TIdHTTP
  2. TIdSSLIOHandlerSocketOpenSSL
  3. TidCookieManager
  4. 在设计时将所有组件相互挂钩,并在运行时进行以下更改:如果协议是纯http:,则断开TIdSSLIOHandlerSocketOpenSSL组件。如果协议是https:,则将IdHTTP的Handler属性设置为IdSSLIOHandlerSocketOpenSSL。

    在SSL选项中,将方法设置为sslvSSLv23,将SSLVersions设置为[sslvSSLv2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]。我发现其他排列这些属性只是不起作用。我无法解释。我只知道这适用于各种各样的网络服务器。

    从那里很容易死。要GET,只需在TIdHTTP上调用Get()方法即可。对于POST,请调用Post()。参数和Cookie可通过明显命名的属性访问。

    我很难将开箱即用的版本正确地发布到POST,但是根据我提到的那样,通过提示修改并设置选项,这是一件轻而易举的事。