Delphi 6和Indy SSL连接无法正常工作

时间:2009-09-14 16:22:05

标签: delphi ssl indy

我需要通过SSL使用Web服务。为了实现这一点,我在Delphi 6中构建了一个Web客户端,它使用Indy读取客户端证书并通过https写入soap请求。代码的编译版本是在IIS 5.0中运行的DLL。在我的本地机器上测试代码后,它工作正常(我在代理后面)。但是在将代码部署到prod服务器(而不是代理服务器)之后,SSL连接失败并显示“使用SSL连接时出错”。

这是我的代码:

var
  Response: TStringStream;
  IdHttp: TIdHTTP;
  IdCnxSLL: TIdConnectionInterceptOpenSSL;
  XmlSoapDoc: IXMLDocument;
begin
  Response := TStringStream.Create('');
  IdHttp := TIdHTTP.Create(nil);
  IdCnxSLL := TIdConnectionInterceptOpenSSL.Create(nil);
  XmlSoapDoc := TXMLDocument.Create(nil);
  with IdCnxSLL do
   begin
    IdCnxSLL.SSLOptions.Method := sslvSSLv23;
    IdCnxSLL.SSLOptions.RootCertFile := IniHttpConnectionData.Values['RootCertFile'];
    IdCnxSLL.SSLOptions.CertFile := IniHttpConnectionData.Values['CertFile'];
    IdCnxSLL.SSLOptions.KeyFile := IniHttpConnectionData.Values['KeyFile'];
    IdCnxSLL.OnGetPassword :=  IdConInterceptOpenSSLGetPassword;
  end;
  with IdHttp do
  begin
    if bUseProxy then
    begin
       Request.ProxyServer := IniHttpConnectionData.Values['ProxyServer'];
       Request.ProxyPort := StrToIntDef(IniHttpConnectionData.Values['ProxyPort'], 0);
    end
    else
    begin
       Host := IniHttpConnectionData.Values['HTTPHost'];
       Port := StrToIntDef(IniHttpConnectionData.Values['HTTPPort'], 443);
    end;
    Request.ContentType := 'text/xml';
    Intercept := IdCnxSLL;
    InterceptEnabled := True;
  end;

  try
    IdHttp.Post(ServiceURL, SoapEnv, Response);
  except
    on E:EIdOSSLConnectError do
       LogError('SSL Connect Error: ' + E.Message);
    on E:Exception do
      LogError('Error' + E.ClassName + ' - ' + E.Message);
  end;

我也尝试将此代码编译成exe程序并且它可以工作。我需要配置/添加其他东西吗?

感谢。

2 个答案:

答案 0 :(得分:3)

您使用TIdConnectionInterceptOpenSSL的事实告诉我您使用的是非常旧版本的Indy。我猜的是与D6一起发售的Indy 8。 Indy 8及更早版本不再由Indy开发团队(我是其成员)正式支持。你真的应该升级到Indy 9,如果没有升级到Indy 10.在Indy 9中,TIdConnectionInterceptOpenSSL被一个新的TIdSSLIOHandlerSocket组件取代。此外,Indy 9及更早版本需要定制的OpenSSL DLL,如果你的Indy版本使用了错误的DLL,也可能导致你的错误。另一方面,Indy 10现在使用OpenSSL网站上的标准DLL。

答案 1 :(得分:2)

Finnally它有效。虽然我强烈建议您使用更新版本的Indy,正如雷米建议的那样。我将发布为我做的技巧的步骤,因为应该有其他人有同样的问题。

我发布的原始代码是有效的,当我们需要通过安全的http(https)发布信息时它起作用,但远程服务器需要使用客户端证书进行事先验证。

为了使其有效,有必要验证以下内容:

  1. TIdHttp和TIdConnectionInterceptOpenSSL配置
  2. 证书
  3. 对于前两个步骤,请按照此处提到的步骤link text或(如果链接已过期)Google“IndySSL - 使用证书身份验证”。它对我有用。

    1. Indy SSL DLL。 (对于D6 / Indy 8,从Indy SSLIntelicom下载indy_openssl096g.zip这个DLL是唯一适用于此版本的Indy的。
    2. 希望这会有所帮助。