简体   繁体   English

如何检查连接是否为SSL?

[英]How to check if a connection is SSL?

I have a C server application that uses OpenSSL and I receive all traffic on the same port. 我有一个使用OpenSSL的C服务器应用程序,并且我在同一端口上接收所有流量。 Is there a safe way to check if incoming data is an SSL connection or something else? 有没有一种安全的方法来检查传入数据是SSL连接还是其他?

The first thing that happens on a TLS connection is the client sending a ClientHello. TLS连接上发生的第一件事是客户端发送ClientHello。 The ClientHello begins with a byte value 22 ( '\\x16' ) identifying it as a handshake message. ClientHello以字节值22'\\x16' )开头,将其标识为握手消息。

If your application protocol is text-based, then it won't contain any 22 bytes (it's not a printable character) so the first byte is sufficient to distinguish your-protocol-over-TCP from your-protocol-over-TLS-over-TCP. 如果您的应用协议是基于文本的,则它将不包含任何22个字节(它不是可打印的字符),因此第一个字节足以区分TCP协议和TLS协议-TCP。

If your application protocol is not text-based, and it's possible for a non-TLS connection to begin with the client sending a 22 byte, you'll have to dig deeper. 如果您的应用协议不是基于文本的,并且非TLS连接有可能从客户端发送22字节开始,那么您就必须进行更深入的研究。 The next 2 bytes are the TLS major and minor version numbers; 接下来的2个字节是TLS主要和次要版本号; currently you can expect the major version byte to be 3 and the minor version byte to be somewhere in the range 1 to 3 . 当前,您可以预期主要版本字节为3 ,次要版本字节在13的范围内。 Lower numbers are possible if you have clients using obsolete, busted versions of SSL, and higher numbers will become possible with future updates to TLS, so you'll have to be flexible. 如果您的客户端使用的是过时的,无效的SSL版本,则可以使用较小的数字,而将来对TLS进行更新时,可以使用较大的数字,因此您必须保持灵活性。

Hopefully you can just rule out 22 as the first byte of the non-TLS version of your protocol. 希望您可以排除22作为协议非TLS版本的第一个字节。

You can use recv with MSG_PEEK to inspect the first byte without consuming it, so after you've made the decision it will still be there for the TLS library or your application protocol to read. 您可以将recvMSG_PEEK结合使用来检查第一个字节而不消耗它,因此在做出决定后,TLS库或您的应用程序协议仍将读取该字节。

Another possible complication: If your application protocol requires the server to speak before the client, you have a problem. 另一个可能的问题是:如果您的应用协议要求服务器在客户端之前讲话,则您有问题。 After the client connects, it might be waiting for your non-TLS greeting, or it might be sending a ClientHello. 客户端连接后,它可能正在等待您的非TLS问候,或者可能正在发送ClientHello。 This problem can only be solved by a timeout - if the client doesn't send anything within some timeframe, assume it's not going to send a ClientHello and go ahead with the non-TLS version of protocol. 这个问题只能通过超时来解决-如果客户端在某个时间范围内未发送任何消息,则假定它不会发送ClientHello并继续使用非TLS版本的协议。 This punishes non-TLS clients with a delay in connection startup, but there's no way to avoid that. 这会给非TLS客户端带来惩罚,它会延迟连接启动,但无法避免这种情况。

If you accept the connections yourself, and hand off to SSL handshaking after you accepted the connection, you need to keep track of it yourself. 如果您自己接受连接,并且在接受连接后切换到SSL握手,则需要自己进行跟踪。

A simple solution is to have a structure containing the accepted socket descriptor, and a boolean flag if it's a SSL connection or not, and have a list of those structures. 一个简单的解决方案是具有一个包含接受的套接字描述符的结构,以及一个布尔标志(如果它不是SSL连接),并具有这些结构的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM