這種公司不去也罷!
時(shí)間:2021-08-19 15:34:16
手機(jī)看文章
掃描二維碼
隨時(shí)隨地手機(jī)看文章
[導(dǎo)讀]大家好,我是小林。上周有位讀者在面試的時(shí)候,碰到這么個(gè)問題:面試官跟他說?HTTPS中的TLS握手過程可以同時(shí)進(jìn)行三次握手,然后讀者之前看我的文章是說「先進(jìn)行TCP三次握手,再進(jìn)行TLS四次握手」,他跟面試官說了這個(gè),面試官說他不對(duì),他就感到很困惑。我們先不管面試官說的那句「HT...
大家好,我是小林。上周有位讀者在面試的時(shí)候,碰到這么個(gè)問題:面試官跟他說?HTTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手,然后讀者之前看我的文章是說「先進(jìn)行 TCP 三次握手,再進(jìn)行 TLS 四次握手」,他跟面試官說了這個(gè),面試官說他不對(duì),他就感到很困惑。
我們先不管面試官說的那句「HTTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手」對(duì)不對(duì)。但是面試官說「HTTPS 建立連接的過程,先進(jìn)行 TCP 三次握手,再進(jìn)行 TLS 四次握手」是錯(cuò)的,這很明顯面試官的水平有問題,這種公司不去也罷!如果是我面試遇到這樣的面試官,我直接當(dāng)場(chǎng)給他抓 HTTPS 建立過程的網(wǎng)絡(luò)包,然后給他看,啪啪啪啪啪的打他臉。比如,下面這個(gè) TLSv1.2 的 基于 RSA 算法的四次握手過程:難道不是先三次握手,再進(jìn)行 TLS 四次握手嗎?面試官你臉疼嗎?不過 TLS 握手過程的次數(shù)還得看版本。TLSv1.2 握手過程基本都是需要四次,也就是需要經(jīng)過 2-RTT 才能完成握手,然后才能發(fā)送請(qǐng)求,而 TLSv1.3 只需要 1-RTT 就能完成 TLS 握手,如下圖。一般情況下,不管 TLS 握手次數(shù)如何,都得先經(jīng)過 TCP 三次握手后才能進(jìn)行,因?yàn)?HTTPS 都是基于 TCP 傳輸協(xié)議實(shí)現(xiàn)的,得先建立完可靠的 TCP 連接才能做 TLS 握手的事情。
不是的,因?yàn)榉?wù)端只有在收到客戶端的 TCP 的第三次握手后,才能和客戶端進(jìn)行后續(xù) TLSv1.3 握手。TLSv1.3 還有個(gè)更厲害到地方在于會(huì)話恢復(fù)機(jī)制,在重連 TLvS1.3 只需要 0-RTT,用“pre_shared_key”和“early_data”擴(kuò)展,在 TCP 連接后立即就建立安全連接發(fā)送加密消息,過程如下圖:TCP Fast Open TLSv1.3
在前面我們知道,客戶端和服務(wù)端同時(shí)支持 TCP Fast Open 功能的情況下,在第二次以后到通信過程中,客戶端可以繞過三次握手直接發(fā)送數(shù)據(jù),而且服務(wù)端也不需要等收到第三次握手后才發(fā)送數(shù)據(jù)。如果 HTTPS 的 TLS 版本是 1.3,那么 TLS 過程只需要 1-RTT。因此如果「TCP Fast Open TLSv1.3」情況下,在第二次以后的通信過程中,TLS 和 TCP 的握手過程是可以同時(shí)進(jìn)行的。如果基于 TCP Fast Open 場(chǎng)景下的 TLSv1.3 0-RTT 會(huì)話恢復(fù)過程,不僅 TLS 和 TCP 的握手過程是可以同時(shí)進(jìn)行的,而且 HTTP 請(qǐng)求也可以在這期間內(nèi)一同完成。
我們先不管面試官說的那句「HTTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手」對(duì)不對(duì)。但是面試官說「HTTPS 建立連接的過程,先進(jìn)行 TCP 三次握手,再進(jìn)行 TLS 四次握手」是錯(cuò)的,這很明顯面試官的水平有問題,這種公司不去也罷!如果是我面試遇到這樣的面試官,我直接當(dāng)場(chǎng)給他抓 HTTPS 建立過程的網(wǎng)絡(luò)包,然后給他看,啪啪啪啪啪的打他臉。比如,下面這個(gè) TLSv1.2 的 基于 RSA 算法的四次握手過程:難道不是先三次握手,再進(jìn)行 TLS 四次握手嗎?面試官你臉疼嗎?不過 TLS 握手過程的次數(shù)還得看版本。TLSv1.2 握手過程基本都是需要四次,也就是需要經(jīng)過 2-RTT 才能完成握手,然后才能發(fā)送請(qǐng)求,而 TLSv1.3 只需要 1-RTT 就能完成 TLS 握手,如下圖。一般情況下,不管 TLS 握手次數(shù)如何,都得先經(jīng)過 TCP 三次握手后才能進(jìn)行,因?yàn)?HTTPS 都是基于 TCP 傳輸協(xié)議實(shí)現(xiàn)的,得先建立完可靠的 TCP 連接才能做 TLS 握手的事情。
那面試官說的這句「HTTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手」對(duì)不對(duì)呢?這個(gè)場(chǎng)景是可能發(fā)生的,但是需要在特定的條件下才可能發(fā)生,如果沒有說任何前提條件,說這句話就是在耍流氓。那到底什么條件下,這個(gè)場(chǎng)景才能發(fā)生呢?需要下面這兩個(gè)條件同時(shí)滿足才可以:
- 客戶端和服務(wù)端都開啟了 TCP Fast Open 功能,且 TLS 版本是 1.3;
- 客戶端和服務(wù)端已經(jīng)完成過一次通信。
TCP Fast Open
我們先來了解下什么是 TCP Fast Open?常規(guī)的情況下,如果要使用 TCP 傳輸協(xié)議進(jìn)行通信,則客戶端和服務(wù)端通信之前,先要經(jīng)過 TCP 三次握手后,建立完可靠的 TCP 連接后,客戶端才能將數(shù)據(jù)發(fā)送給服務(wù)端。其中,TCP 的第一次和第二次握手是不能夠攜帶數(shù)據(jù)的,而 TCP 的第三次握手是可以攜帶數(shù)據(jù)的,因?yàn)檫@時(shí)候客戶端的 TCP 連接狀態(tài)已經(jīng)是 ESTABLISHED,表明客戶端這一方已經(jīng)完成了 TCP 連接建立。就算客戶端攜帶數(shù)據(jù)的第三次握手在網(wǎng)絡(luò)中丟失了,客戶端在一定時(shí)間內(nèi)沒有收到服務(wù)端對(duì)該數(shù)據(jù)的應(yīng)答報(bào)文,就會(huì)觸發(fā)超時(shí)重傳機(jī)制,然后客戶端重傳該攜帶數(shù)據(jù)的第三次握手的報(bào)文,直到重傳次數(shù)達(dá)到系統(tǒng)的閾值,客戶端就會(huì)銷毀該 TCP 連接。說完常規(guī)的 TCP 連接后,我們?cè)賮砜纯?TCP Fast Open。TCP Fast Open 是為了繞過 TCP 三次握手發(fā)送數(shù)據(jù),在 Linux 3.7 內(nèi)核版本之后,提供了 TCP Fast Open 功能,這個(gè)功能可以減少 TCP 連接建立的時(shí)延。要使用 TCP Fast Open 功能,客戶端和服務(wù)端都要同時(shí)支持才會(huì)生效。不過,開啟了 TCP Fast Open 功能,想要繞過 TCP 三次握手發(fā)送數(shù)據(jù),得建立第二次以后的通信過程。在客戶端首次建立連接時(shí)的過程,如下圖:具體介紹:
- 客戶端發(fā)送 SYN 報(bào)文,該報(bào)文包含 Fast Open 選項(xiàng),且該選項(xiàng)的 Cookie 為空,這表明客戶端請(qǐng)求 Fast Open Cookie;
- 支持 TCP Fast Open 的服務(wù)器生成 Cookie,并將其置于 SYN-ACK 報(bào)文中的 Fast Open 選項(xiàng)以發(fā)回客戶端;
- 客戶端收到 SYN-ACK 后,本地緩存 Fast Open 選項(xiàng)中的 Cookie。
- 客戶端發(fā)送 SYN 報(bào)文,該報(bào)文可以攜帶「應(yīng)用數(shù)據(jù)」以及此前記錄的 Cookie;
- 支持 TCP Fast Open 的服務(wù)器會(huì)對(duì)收到 Cookie 進(jìn)行校驗(yàn):如果 Cookie 有效,服務(wù)器將在 SYN-ACK 報(bào)文中對(duì) SYN 和「數(shù)據(jù)」進(jìn)行確認(rèn),服務(wù)器隨后將「應(yīng)用數(shù)據(jù)」遞送給對(duì)應(yīng)的應(yīng)用程序;如果 Cookie 無效,服務(wù)器將丟棄 SYN 報(bào)文中包含的「應(yīng)用數(shù)據(jù)」,且其隨后發(fā)出的 SYN-ACK 報(bào)文將只確認(rèn) SYN 的對(duì)應(yīng)序列號(hào);
- 如果服務(wù)器接受了 SYN 報(bào)文中的「應(yīng)用數(shù)據(jù)」,服務(wù)器可在握手完成之前發(fā)送「響應(yīng)數(shù)據(jù)」,這就減少了握手帶來的 1 個(gè) RTT 的時(shí)間消耗;
- 客戶端將發(fā)送 ACK 確認(rèn)服務(wù)器發(fā)回的 SYN 以及「應(yīng)用數(shù)據(jù)」,但如果客戶端在初始的 SYN 報(bào)文中發(fā)送的「應(yīng)用數(shù)據(jù)」沒有被確認(rèn),則客戶端將重新發(fā)送「應(yīng)用數(shù)據(jù)」;
- 此后的 TCP 連接的數(shù)據(jù)傳輸過程和非 TCP Fast Open 的正常情況一致。
TLSv1.3
說完 TCP Fast Open,再來看看 TLSv1.3。在最開始的時(shí)候,我也提到 TLSv1.3 握手過程只需 1-RTT 的時(shí)間,它到整個(gè)握手過程,如下圖:TCP 連接的第三次握手是可以攜帶數(shù)據(jù)的,如果客戶端在第三次握手發(fā)送了 TLSv1.3 第一次握手?jǐn)?shù)據(jù),是不是就表示「HTTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手」?。
不是的,因?yàn)榉?wù)端只有在收到客戶端的 TCP 的第三次握手后,才能和客戶端進(jìn)行后續(xù) TLSv1.3 握手。TLSv1.3 還有個(gè)更厲害到地方在于會(huì)話恢復(fù)機(jī)制,在重連 TLvS1.3 只需要 0-RTT,用“pre_shared_key”和“early_data”擴(kuò)展,在 TCP 連接后立即就建立安全連接發(fā)送加密消息,過程如下圖:
TCP Fast Open TLSv1.3
在前面我們知道,客戶端和服務(wù)端同時(shí)支持 TCP Fast Open 功能的情況下,在第二次以后到通信過程中,客戶端可以繞過三次握手直接發(fā)送數(shù)據(jù),而且服務(wù)端也不需要等收到第三次握手后才發(fā)送數(shù)據(jù)。如果 HTTPS 的 TLS 版本是 1.3,那么 TLS 過程只需要 1-RTT。因此如果「TCP Fast Open TLSv1.3」情況下,在第二次以后的通信過程中,TLS 和 TCP 的握手過程是可以同時(shí)進(jìn)行的。如果基于 TCP Fast Open 場(chǎng)景下的 TLSv1.3 0-RTT 會(huì)話恢復(fù)過程,不僅 TLS 和 TCP 的握手過程是可以同時(shí)進(jìn)行的,而且 HTTP 請(qǐng)求也可以在這期間內(nèi)一同完成。總結(jié)
最后做個(gè)總結(jié)?!窰TTPS 是先進(jìn)行 TCP 三次握手,再進(jìn)行 TLSv1.2 四次握手」,這句話一點(diǎn)問題都沒有,懷疑這句話是錯(cuò)的人,才有問題?!窰TTPS 中的 TLS 握手過程可以同時(shí)進(jìn)行三次握手」,這個(gè)場(chǎng)景是可能存在到,但是在沒有說任何前提條件,而說這句話就等于耍流氓。需要下面這兩個(gè)條件同時(shí)滿足才可以:- 客戶端和服務(wù)端都開啟了 TCP Fast Open 功能,且 TLS 版本是 1.3;
- 客戶端和服務(wù)端已經(jīng)完成過一次通信;