当我将SSl添加到Delphi 2010中的Indy Zip Code Lookup示例时,为什么会出现“错误的版本错误”?

时间:2015-03-03 05:21:34

标签: delphi ssl indy

我想我会尝试一些简单的尝试来理解Web客户端/服务器应用程序,因为我对此一无所知,但我需要学习。我下载了"邮政编码查询"来自Web(客户端和服务器)的示例。编译它们,一切按宣传方式工作。

然后我在每个表单上删除了一个SSL IO Handler,并将它们指定为处理程序" sslvTLSv1"两者都选中了。现在它没有用。每当我尝试在客户端应用程序中查找邮政编码时,我得到,"错误:1408F10B:SSL例程:SSL3_GET_RECORD:错误的版本号。"我卸载了原始的Indy库并安装了最新版本(10.6.2.5264)。可以肯定的是,我获得了最新的SSL库并将它们放在两个程序文件夹中。

我在Indy看过很多关于SSL的问题和答案,看起来它应该有效。我错过了什么?

这是服务器DFM的相关部分:

object IdTCPServer1: TIdTCPServer
  Active = True
  Bindings = <
    item
      IP = '127.0.0.1'
      Port = 6000
    end>
  DefaultPort = 6000
  IOHandler = Handler
  OnConnect = IdTCPServer1Connect
  OnExecute = IdTCPServer1Execute
  Left = 32
  Top = 24
end
object Handler: TIdServerIOHandlerSSLOpenSSL
  SSLOptions.Mode = sslmServer
  SSLOptions.VerifyMode = []
  SSLOptions.VerifyDepth = 0
  Left = 100
  Top = 32
end

这是客户DFM的相关部分。

object Client: TIdTCPClient
  IOHandler = Handler
  ConnectTimeout = 0
  Host = '127.0.0.1'
  IPVersion = Id_IPv4
  Port = 6000
  ReadTimeout = -1
  Left = 209
  Top = 16
end
object Handler: TIdSSLIOHandlerSocketOpenSSL
  Destination = '127.0.0.1:6000'
  Host = '127.0.0.1'
  MaxLineAction = maException
  Port = 6000
  DefaultPort = 0
  SSLOptions.Mode = sslmClient
  SSLOptions.VerifyMode = []
  SSLOptions.VerifyDepth = 0
  Left = 296
  Top = 32
end

在尝试了Remy的建议之后

我添加了将PassThrough设置为false的代码,现在我得到了一个不同的错误。 &#34;错误:14094410:SSL例程:ssl3_read_bytes:sslv3警报握手失败。&#34;

对于那些想要查看源代码的人来说,它位于http://www.atozedsoftware.com/indy/demos/10/index.EN.aspx的网络上(我正在使用服务器的OnExecute版本)。现在唯一的区别是每个单元中的线路设置PassThrough模式。

在服务器代码中:

procedure TformMain.IdTCPServer1Connect(AContext: TIdContext);
begin
  TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
  AContext.Connection.IOHandler.WriteLn('200 Zip Code Server Ready.');
  AContext.Data := TUserData.Create;
end;

在客户端代码中:

procedure TformMain.butnLookupClick(Sender: TObject);
var
  i: integer;
begin
  butnLookup.Enabled := False; try
    lboxResults.Clear;
    Handler.PassThrough := False;

2 个答案:

答案 0 :(得分:3)

您没有显示任何代码,只显示了您的DFM。这还不够。但我怀疑可能发生的是你在客户端将IOHandler.PassThrough属性设置为false,但在服务器端没有这样做。

当客户端连接到TIdTCPServer时,默认情况下服务器不会激活SSL / TLS,因此在决定是否需要SSL / TLS之前,服务器可以分析客户端,甚至可能不安全地与客户端进行通信。这是为了方便服务器在多个端口上侦听,而不是所有端口都使用SSL / TLS(比如HTTP与HTTPS),并处理基于STARTTLS的协议。

因此,如果您尚未这样做,请确保在连接的两端将IOHandler.PassThrough设置为false,例如:

Handler.PassThrough := False;
IdTCPClient1.Connect;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
  TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := False;
end;

如果您确实在两端都这样做,但仍然遇到相同的错误,请确保两端的IOHandler.SSLOptions.SSLMethod / IOHandler.SSLOptions.TLSVersions属性配置正确,并且它们使用的是兼容设置。你说你在两端使用TLSv1,所以你不应该得到错误,除非服务器真的没有使用TLSv1。

答案 1 :(得分:0)

所以,最后我不得不做一些更多的事情,而不是放弃表格上的几个控件。

首先,我必须添加代码以将每个SSL控件的PassThrough属性设置为false(可能它们应该是已发布的属性?)。

然后我必须安装有效的证书并在服务器端设置CertFile,KeyFile和RootCertFile属性。

现在有效!

感谢Remy的帮助,BTW使用的是OpenSSL v1.0.2和Indy 10.5.5。在使用Delphi 2010的Win32(Vista)中。