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