【问题标题】:How to check if a connection is SSL?如何检查连接是否为 SSL?
【发布时间】:2016-04-26 13:06:25
【问题描述】:

我有一个使用 OpenSSL 的 C 服务器应用程序,并且我在同一个端口上接收所有流量。有没有一种安全的方法来检查传入的数据是 SSL 连接还是其他什么?

【问题讨论】:

  • 您的意思是您使用单个端口接受服务器中的所有连接,然后在接受连接后进行 SSL 协商?您不使用库函数为您处理连接?
  • 是的。我应该决定哪种流量,然后如果是 SSL 则进行 SSL 协商,否则以另一种方式处理。

标签: c sockets openssl


【解决方案1】:

在 TLS 连接上发生的第一件事是客户端发送 ClientHello。 ClientHello 以字节值 22 ('\x16') 开头,将其标识为握手消息。

如果您的应用程序协议是基于文本的,那么它将不包含任何 22 字节(它不是可打印字符),因此第一个字节足以区分 your-protocol-over-TCP 和 your-protocol- over-TLS-over-TCP。

如果您的应用程序协议不是基于文本的,并且非 TLS 连接可能以客户端发送 22 字节开始,您将不得不深入挖掘。接下来的 2 个字节是 TLS 主要和次要版本号;目前,您可以预期主要版本字节为3,次要版本字节位于13 范围内。如果您的客户端使用过时的、被破坏的 SSL 版本,则可以使用较低的数字,而随着 TLS 的未来更新,可以使用更高的数字,因此您必须灵活。

希望您可以排除 22 作为协议的非 TLS 版本的第一个字节。

您可以使用 recvMSG_PEEK 来检查第一个字节而不消耗它,因此在您做出决定后,它仍然会在那里供 TLS 库或您的应用程序协议读取。

另一个可能的复杂情况:如果您的应用程序协议要求服务器先于客户端说话,那么您就有问题了。客户端连接后,它可能正在等待您的非 TLS 问候,或者它可能正在发送 ClientHello。这个问题只能通过超时来解决——如果客户端在某个时间范围内没有发送任何东西,假设它不会发送 ClientHello 并继续使用非 TLS 版本的协议。这会通过延迟连接启动来惩罚非 TLS 客户端,但没有办法避免这种情况。

【讨论】:

  • ......当我们不是指旧的破坏版本时,让我们都停止使用名称“SSL”作为协议。 TLS 已经在这里了!
  • 非常感谢,这正是我正在寻找的答案!
【解决方案2】:

如果您自己接受连接,并在接受连接后切换到 SSL 握手,您需要自己跟踪它。

一个简单的解决方案是拥有一个包含接受的套接字描述符的结构,以及一个布尔标志(如果它是 SSL 连接),并拥有这些结构的列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2017-03-04
    • 2012-08-05
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多