Delphi 6 和 Indy SSL 连接无法正常工作
题
我需要通过 SSL 使用 Web 服务。为了实现这一目标,我在 Delphi 6 中构建了一个 Web 客户端,它使用 Indy 读取客户端证书并通过 https 写入肥皂请求。代码的编译版本是在 IIS 5.0 中运行的 DLL。在我的本地计算机中测试代码后,它工作正常(我在代理后面)。但是,将代码部署到产品服务器(而非代理)后,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
终于成功了。尽管我强烈建议您按照雷米的建议使用较新版本的 Indy。我将发布对我有用的步骤,因为应该有其他人遇到同样的问题。
我发布的原始代码是有效的,当我们需要通过安全的 http (https) 发布信息但远程服务器需要使用客户端证书进行事先身份验证时,它可以工作。
为了使其正常工作,需要验证以下内容:
- TIdHttp 和 TIdConnectionInterceptOpenSSL 配置
- 证书
对于前 2 个步骤,请按照此处提到的步骤操作 链接文本 或(如果链接已过期)Google“IndySSL - 使用证书身份验证”。这对我有用。
- Indy SSL DLL。(对于 D6/Indy 8,请从以下位置下载 indy_openssl096g.zip 印地 SSL 或者 英特尔公司)这个 DLL 是唯一适用于此版本 Indy 的 DLL。
希望这会有所帮助。
其他提示
您使用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。