5

我正在尝试使用 Indy 和 OpenSSL 在 Delphi XE3 中设置一个 Web 服务器,该服务器可以通过同一端口上的 HTTP 和 HTTPS 连接提供流量。

我已经看到了两种主要的方法,但似乎都不适合我。

第一:前期 TLS/SSL。这涉及读取流的前几个字节以查找非安全握手的“Client-Hello”部分并(如果找到)调用服务器 SSL 握手响应,但如果我这样做,OpenSSL 库将无法识别握手,因为我已经剥离了消息的前导字节。

第二:在 STARTTLS(或等效)之后的 TLS。这涉及发送一组特殊的字符 (STARTTLS),紧随其后的是“Client-Hello”。然后服务器将整个 SSL 握手消息保持原样以传递给 OpenSSL 库。这种方法的问题是大多数网络浏览器不支持它(RFC 2817)。

有关这两种方法的摘要,请查看此处: 当建立 TLS / LDAP 或 TLS / HTTP 连接时,线路上会发生什么?)

如何使用 TIdHTTPServer 和 OpenSSL 在同一端口上支持 SSL 和非 SSL 流量?

4

1 回答 1

1

开箱即用的 Indy 无法满足您的要求。 Indy 的默认 SSL 实现使用 OpenSSL 的传统 API,它执行所有自己的套接字 I/O,因此它需要直接访问完整的握手数据,而无需让您先查看数据。然而,一切都没有丢失。你有几个选择:

1) 在套接字将其提供给您的应用程序之前,使用 libpcap/Winpcap 捕获并查看来自线路的原始数据的前几个字节以进行新连接。

2) 编写自己的TIdIOHandler派生类,使用 OpenSSL 的较新 BIO API 或 Microsoft 的 SChannel API,因此您可以控制套接字 I/O,并且可以自己读取传入字节并在将它们推入加密引擎进行处理之前查看它们。

更新:实际上有第三个选项,使用 Indy 的默认类:

3) 在TIdHTTPServer.OnQuerySSLPort事件中,将VUseSSL参数设置False为所有请求,从而关闭TIdHTTPServerSSL/TLS 握手的自动处理。然后,在TIdHTTPServer.OnConnect事件中(在事件之后触发OnQuerySSLPort),您可以直接从套接字连接中查看前几个字节(使用带有套接字句柄和标志的操作系统的套接字 APIrecv()函数)。如果偷看的字节表示“Client-Hello”SSL/TLS 消息的开始,则将对象类型转换为并将其属性设置为以启动 OpenSSL 的正常 SSL/TLS 握手处理。由于偷看的字节仍将在套接字的内部缓冲区中,因此 OpenSSL 将能够读取它们。AContext.Binding.HandleMSG_PEEKAContext.Connection.IOHandlerTIdSSLIOHandlerSocketBasePassThroughFalse

于 2013-04-26T15:09:33.657 回答