为什么我在 Delphi 2010 中将 SSl 添加到 Indy 邮政编码查找示例时得到 "wrong version error"?
Why do I get "wrong version error" when I add SSl to the Indy Zip Code Lookup example in Delphi 2010?
我想我会尝试一些简单的东西来尝试理解 Web client/server 应用程序,因为我对此一无所知,但我需要学习。我从网络(客户端和服务器)下载了 "Zip Code look up" 示例。编译它们,一切都像宣传的那样工作。
然后我在每个表单上放置了一个 SSL IO 处理程序,并将它们指定为处理程序,并在两个表单中都选择了 "sslvTLSv1"。现在它不起作用。每次我尝试在客户端应用程序中查找邮政编码时,我都会 "error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number." 我卸载了原始的 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 的代码,但现在出现了不同的错误。
"error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure."
对于那些想要查看源代码的人,它位于 http://www.atozedsoftware.com/indy/demos/10/index.EN.aspx 的 Web 上(我使用的是服务器的 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;
您没有显示任何代码,只显示了您的 DFM。这还不够。但我怀疑 可能 发生的是你在客户端将 IOHandler.PassThrough
属性 设置为 false,但在服务器端没有做同样的事情.
当客户端连接到 TIdTCPServer
时,SSL/TLS 默认情况下不会被服务器激活,因此服务器可以分析客户端,甚至可能与它进行不安全的通信,然后再决定是否 [=30] =] 是必需的。这是为了方便服务器侦听多个端口,而并非所有端口都使用 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。
所以,最后我要做的不仅仅是在窗体上放置几个控件。
首先,我必须添加代码以将每个 SSL 控件的 PassThrough 属性 设置为 false(也许它们应该是已发布的属性?)。
然后我必须安装一个有效的证书并在服务器端设置 CertFile、KeyFile 和 RootCertFile 属性。
现在可以使用了!
感谢 Remy 的帮助,顺便说一句,这是使用 OpenSSL v1.0.2 和 Indy 10.5.5。在 Win32 (Vista) 中 Delphi 2010.
我想我会尝试一些简单的东西来尝试理解 Web client/server 应用程序,因为我对此一无所知,但我需要学习。我从网络(客户端和服务器)下载了 "Zip Code look up" 示例。编译它们,一切都像宣传的那样工作。
然后我在每个表单上放置了一个 SSL IO 处理程序,并将它们指定为处理程序,并在两个表单中都选择了 "sslvTLSv1"。现在它不起作用。每次我尝试在客户端应用程序中查找邮政编码时,我都会 "error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number." 我卸载了原始的 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 的代码,但现在出现了不同的错误。 "error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure."
对于那些想要查看源代码的人,它位于 http://www.atozedsoftware.com/indy/demos/10/index.EN.aspx 的 Web 上(我使用的是服务器的 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;
您没有显示任何代码,只显示了您的 DFM。这还不够。但我怀疑 可能 发生的是你在客户端将 IOHandler.PassThrough
属性 设置为 false,但在服务器端没有做同样的事情.
当客户端连接到 TIdTCPServer
时,SSL/TLS 默认情况下不会被服务器激活,因此服务器可以分析客户端,甚至可能与它进行不安全的通信,然后再决定是否 [=30] =] 是必需的。这是为了方便服务器侦听多个端口,而并非所有端口都使用 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。
所以,最后我要做的不仅仅是在窗体上放置几个控件。
首先,我必须添加代码以将每个 SSL 控件的 PassThrough 属性 设置为 false(也许它们应该是已发布的属性?)。
然后我必须安装一个有效的证书并在服务器端设置 CertFile、KeyFile 和 RootCertFile 属性。
现在可以使用了!
感谢 Remy 的帮助,顺便说一句,这是使用 OpenSSL v1.0.2 和 Indy 10.5.5。在 Win32 (Vista) 中 Delphi 2010.