2016-04-26 129 views
1

我有一個使用OpenSSL的C服務器應用程序,並且我收到同一端口上的所有流量。有沒有安全的方法來檢查傳入的數據是SSL連接還是其他?如何檢查連接是否爲SSL?

+1

您的意思是說您接受服務器中所有使用單個端口的連接,然後在接受連接後進行SSL協商?你不使用庫函數來爲你處理連接? –

+0

是的。我應該決定使用哪種類型的流量,然後是SSL進行SSL協商,否則以另一種方式處理。 – Marco

回答

2

發生在TLS連接上的第一件事是發送ClientHello的客戶端。 ClientHello以字節值22'\x16')開始,將其標識爲握手消息。

如果你的應用協議是基於文本的,那麼它將不包含任何22字節(它不是可打印的字符),所以第一個字節足以區分TCP協議和TCP協議。 -TLS環比TCP。

如果您的應用協議不是基於文本的,並且非客戶端發送22字節時可能會出現非TLS連接,那麼您需要深入瞭解。接下來的2個字節是TLS主版本號和次版本號;目前您可以預期主版本字節爲3,次版本字節在13的範圍內。如果客戶使用過時的,破壞的SSL版本,則可能會有更少的數字,並且隨着TLS將來的更新,更高的數字將成爲可能,因此您必須靈活。

希望您可以排除22作爲您的協議的非TLS版本的第一個字節。

您可以使用recvMSG_PEEK檢查第一個字節而不消耗它,因此在做出決定後,它仍然會在TLS庫或應用程序協議中讀取。

另一種可能的併發症:如果您的應用程序協議要求服務器在客戶端之前發言,則說明您有問題。客戶端連接後,它可能正在等待您的非TLS問候語,或者它可能正在發送ClientHello。這個問題只能通過超時來解決 - 如果客戶端在某個時間段內沒有發送任何內容,則認爲它不會發送ClientHello並繼續使用非TLS版本的協議。這會延遲啓動連接時懲罰非TLS客戶端,但無法避免這種情況。

+1

...並且當我們不提及舊的破壞版本時,我們都停止使用協議名稱「SSL」。 TLS已經在這裏了! –

+0

非常感謝,這就是我一直在尋找的答案! – Marco

0

如果您自己接受連接,並在接受連接後切換到SSL握手,則需要自行跟蹤。

一個簡單的解決方案是擁有一個包含接受的套接字描述符和一個布爾標誌(如果它是一個SSL連接或不是)的結構,並具有這些結構的列表。