HTTPS 是如何運(yùn)作的?它解決了什么問(wèn)題?-每日消息

來(lái)源:SH的全棧筆記

首先,HTTPS 并不是一個(gè)新的協(xié)議,而是 HTTP + SSL/TLS,即 SSL(Security SocketLayer)和 TLS(TransportLayerSecurity) 的縮寫(xiě)。但其實(shí)作為 SSL 的繼任者,TLS 已經(jīng)完全替代了 SSL,只是大概還是習(xí)慣使用 SSL 這個(gè)名詞。為了嚴(yán)謹(jǐn),后續(xù)都會(huì)繼續(xù)使用 TLS。


(資料圖片)

簡(jiǎn)單了解 HTTP從何而來(lái)

要了解 HTTPS,自然我們要先了解 HTTP 協(xié)議,最初 HTTP 協(xié)議的出現(xiàn)是為了讓全球的研究者知識(shí)共享而發(fā)明出來(lái)的,它于 1990 年被發(fā)明出來(lái),但這一版本的 HTTP 協(xié)議并沒(méi)有作為標(biāo)準(zhǔn)。

HTTP/0.9

Tim Berners-Lee 和他的團(tuán)隊(duì)提出這個(gè)最早的 HTTP/0.9 版本存在一些不明確的地方,例如:

沒(méi)有版本標(biāo)識(shí),不像現(xiàn)在我們有 HTTP/0.9、HTTP/1.0、HTTP/1.1 等等,就連這個(gè) 0.9 都是后面才加上的沒(méi)有請(qǐng)求頭,只有一個(gè)簡(jiǎn)簡(jiǎn)單單普普通通的 GET 請(qǐng)求響應(yīng)只支持 HTML 文檔本身,不支持其他的格式,比如圖片、視頻沒(méi)有狀態(tài)碼,根本不知道請(qǐng)求是否成功,或者是因?yàn)槭裁丛蚴《踢B接,也是就是后面 HTTP/1.1 和部分的 HTTP/1.0 提出 Keep-Alive 要解決的問(wèn)題

這就是最初的 HTTP,存在很多的缺陷,也難怪沒(méi)有成為標(biāo)準(zhǔn)。

HTTP/1.0

到了1996年5月,HTTP 提出了新的版本 HTTP/1.0,而它也成了 HTTP 第一個(gè)正式的版本,也被正式的標(biāo)準(zhǔn)化。它解決了 HTTP/0.9 沒(méi)有解決的問(wèn)題,例如:

引入了明確的版本號(hào)定義了請(qǐng)求頭、響應(yīng)頭,這讓請(qǐng)求中能夠附件傳輸很多的元數(shù)據(jù),這些頭都是基礎(chǔ),不再贅述支持了多種數(shù)據(jù)類型,例如圖片、音頻、視頻引入了狀態(tài)碼引入了緩存機(jī)制

我們現(xiàn)在之后后續(xù)的主流版本其實(shí)是 HTTP/1.1,這說(shuō)明當(dāng)時(shí)提出的 HTTP/1.0 其實(shí)還是存在部分的問(wèn)題。

HTTP/1.1

1997年1月,HTTP/1.1 發(fā)布,這也是在 HTTP/2.0 出來(lái)之前最為主流的版本,我們來(lái)看看它解決了什么問(wèn)題就知道 HTTP/1.0 存在的缺陷了。

引入了持久化連接機(jī)制基于 Keep-Alive 長(zhǎng)連接,推出了管線化技術(shù),提高了發(fā)送請(qǐng)求的速度引入了更加靈活的緩存機(jī)制分塊傳輸范圍請(qǐng)求

所謂持久化連接機(jī)制,即服用底層的 TCP 連接。HTTP 底層通信使用的是 TCP,在 HTTP/1.1 之前都是發(fā)起一個(gè) HTTP 請(qǐng)求就會(huì)建立一個(gè) TCP 連接,傳輸數(shù)據(jù)之后再斷開(kāi)。這波操作在 HTTP/1.0 那個(gè)時(shí)間是沒(méi)問(wèn)題的,HTTP 沒(méi)普及,傳輸?shù)膬?nèi)容也都是小容量的文本。但隨著 HTTP 的普及,傳輸?shù)膬?nèi)容變得也越來(lái)越來(lái)豐富,況且還新增了圖片、音視頻。像這樣頻繁的發(fā)起、斷開(kāi) TCP 連接會(huì)大大的增加頁(yè)面資源的加載速度,降低用戶的體驗(yàn)。所謂持久化連接也就是,只要任意一方?jīng)]有提出斷開(kāi) TCP 連接,就繼續(xù)復(fù)用這個(gè)連接,減少了創(chuàng)建連接帶來(lái)的開(kāi)銷。

而管線化技術(shù)則是發(fā)送一個(gè)請(qǐng)求不用等待其響應(yīng),繼續(xù)發(fā)送下一個(gè)請(qǐng)求。沒(méi)有管線化技術(shù)時(shí),必須等待上一個(gè)請(qǐng)求響應(yīng)回來(lái)之后才能發(fā)送下一個(gè)請(qǐng)求,而這種機(jī)制在網(wǎng)絡(luò)較慢的情況下會(huì)引發(fā)一個(gè)問(wèn)題——隊(duì)頭阻塞。比如,請(qǐng)求一張較大的圖片,偏偏網(wǎng)絡(luò)還慢,那么后續(xù)的請(qǐng)求都會(huì)被阻塞。但管線化技術(shù)解決了這個(gè)問(wèn)題嗎?解決了一部分,沒(méi)有完全解決。采用管線化技術(shù),請(qǐng)求雖然發(fā)出去了,但它是有序的, 所以在等待響應(yīng)時(shí),這一批里有響應(yīng)遲遲沒(méi)有回來(lái),后續(xù)的請(qǐng)求仍然要等待。所以這個(gè)問(wèn)題并沒(méi)有完全解決。

HTTP/2.0

既然有問(wèn)題,那么后續(xù)就需要有新的版本來(lái)解決這些問(wèn)題。2015年5月,HTTP/2.0 正式標(biāo)準(zhǔn)化,之后慢慢開(kāi)始大面積的普及,那么它又解決了哪些問(wèn)題呢?主要如下:

提出了多路復(fù)用,解決了 HTTP/1.1 中的隊(duì)頭阻塞問(wèn)題使用了二進(jìn)制協(xié)議,而不是原來(lái)的文本協(xié)議對(duì)頭部進(jìn)行壓縮,減少每個(gè) HTTP 請(qǐng)求的頭部大小,減少了傳輸?shù)臄?shù)據(jù)大小支持服務(wù)器推送,HTTP/2.0 允許服務(wù)器主動(dòng)推送資源到客戶端,減少客戶端的請(qǐng)求次數(shù)

當(dāng)然,相信你也知道,現(xiàn)在 HTTP/3.0 也出來(lái)了,其關(guān)鍵的改動(dòng)在于將底層傳輸層的協(xié)議從 TCP 切換到了QUIC,其底層采用的是 UDP,這個(gè)后面有機(jī)會(huì)單獨(dú)寫(xiě)一篇文章來(lái)介紹。

Why HTTPS?

HTTP 即使推出了很多個(gè)版本,但是仍然存在問(wèn)題,例如:

協(xié)議本身沒(méi)有加密,再加上底層使用的 TCP/IP 本身就在很多環(huán)節(jié)容易被竊聽(tīng),例如我們熟悉的 Wireshark沒(méi)有驗(yàn)證通信方的身份,可能遭遇偽裝無(wú)法校驗(yàn)數(shù)據(jù)是否被篡改混合加密

所以這才有了 HTTPS,也就是 HTTP + TLS。

在 HTTP 協(xié)議中,由它本身直接和 HTTP 通信,而在 HTTPS 協(xié)議中,HTTP 是和 TLS 進(jìn)行通信,相當(dāng)于給套了一層娃,加了個(gè)中間層。

那要如何進(jìn)行加密呢?

HTTPS 采用了混合加密的方式,大致的流程如下:

客戶端訪問(wèn)服務(wù)器,服務(wù)器會(huì)返回自己的公鑰客戶端生成一個(gè)隨機(jī)密鑰,使用上一步獲取的公鑰對(duì)隨機(jī)密鑰進(jìn)行加密將用服務(wù)器公鑰加密后的客戶端隨機(jī)密鑰發(fā)送給服務(wù)器服務(wù)器用自己的私鑰進(jìn)行解密,拿到客戶端的隨機(jī)密鑰明文

到這里,客戶端和瀏覽器就將后續(xù)通信加解密要使用到的密鑰安全的進(jìn)行了傳輸,后續(xù)客戶端服務(wù)器的所有通信都會(huì)使用這個(gè)隨機(jī)密鑰。所謂的混合加密就是即使用了對(duì)稱加密,也使用了非對(duì)稱加密。

中間人攻擊

但是這個(gè)步驟有個(gè)比較明顯的問(wèn)題,即——中間人攻擊。

還是基于上面的這個(gè)步驟,客戶端以為自己在和服務(wù)器通信,實(shí)際上它在和中間人通信,然后中間人將服務(wù)器的真正公鑰 S 保存了下來(lái),然后把中間人自己的公鑰 B 返回給了客戶端。

客戶端拿到了中間人的公鑰 B,然后使用公鑰 B 對(duì)其生成的隨機(jī)密鑰進(jìn)行加密,然后傳給中間人。中間人拿到了加密密文,使用自己的私鑰 B’ 進(jìn)行解密,到這里就拿到了客戶端的隨機(jī)密鑰。然后再用保存好的服務(wù)器真正公鑰 S 加密,將密文再傳給服務(wù)器。其流程如下圖所示:

中間人攻擊示意圖

這樣就完成了一波套娃,并且客戶端和服務(wù)器都沒(méi)有感知。這樣一來(lái),一旦攻擊成功,后續(xù)的通信中間人都能夠通過(guò)前面步驟拿到的隨機(jī)密鑰進(jìn)行解密,然后篡改,再加密傳給服務(wù)器。

那該如何解決這個(gè)問(wèn)題呢?

在上面的流程中,其關(guān)鍵的問(wèn)題在于客戶端無(wú)法證明服務(wù)器返回的公鑰的正確性,它可能是中間人的公鑰,而不是服務(wù)器的。如果有某種方式能夠讓我們確認(rèn),這個(gè)公鑰的的確確就是服務(wù)器的真實(shí)公鑰,上面的問(wèn)題就迎刃而解了。

而這就是 CA。

CA 證書(shū)

全稱為CertificateAuthority,它是一個(gè)機(jī)構(gòu),可以將其理解為客戶端和服務(wù)器都可以信賴的一個(gè)第三方。開(kāi)發(fā)人員會(huì)將服務(wù)器的真實(shí)公鑰提供給 CA,然后 CA 判斷服務(wù)器的身份之后,會(huì)對(duì)公鑰簽名,然后將其和 CA 證書(shū)綁定在一起。當(dāng)然 CA 證書(shū)包含的不僅僅只有簽名,還有序列號(hào)、用途、頒發(fā)者、有效時(shí)間之類的。

然后客戶端來(lái)請(qǐng)求公鑰時(shí),服務(wù)器會(huì)直接把證書(shū)返回給客戶端。那么問(wèn)題又來(lái)了,你怎么能夠保證返回的證書(shū)不是由中間人返回的?加了個(gè) CA 就能夠解決這個(gè)問(wèn)題嗎?

當(dāng)然不是。

客戶端還會(huì)對(duì) CA 證書(shū)進(jìn)行校驗(yàn),以此來(lái)保證:

CA 機(jī)構(gòu)值得信賴服務(wù)器的公鑰真實(shí)有效

否則仍然會(huì)面臨中間人攻擊的風(fēng)險(xiǎn)。那客戶端是如何驗(yàn)證這兩點(diǎn)的呢?

首先,在將服務(wù)器公鑰提供給 CA 時(shí),CA 會(huì)使用自己的私鑰對(duì)服務(wù)器公鑰進(jìn)行簽名。注意,這里是私鑰,不是公鑰。然后客戶端拿到這個(gè)證書(shū)之后,會(huì)使用 CA 的公鑰(內(nèi)置在瀏覽器中)對(duì)其進(jìn)行解密,然后拿到 CA 側(cè)登記證書(shū)時(shí)計(jì)算的 Hash 值,然后客戶端會(huì)根據(jù)證書(shū)上的信息,使用同樣的算法計(jì)算出另一個(gè) Hash 值,然后將這兩個(gè) Hash 值對(duì)比,就能夠知道證書(shū)是否可信賴。當(dāng)然,這個(gè)只是其中的一個(gè)步驟,CA 的認(rèn)證還涉及到信任鏈的問(wèn)題,這里不展開(kāi)。

當(dāng)然,CA 也不能解決全部的問(wèn)題。之前也出過(guò) CA 機(jī)構(gòu)被黑的事故,非法頒發(fā)了 Google 和 Twitter 的偽造證書(shū)。

HTTPS 握手過(guò)程

握手的過(guò)程,總結(jié)成了一張圖,其實(shí)就是將上面將的 HTTPS 的加密原理細(xì)化了一下:

標(biāo)簽:

推薦

財(cái)富更多》

動(dòng)態(tài)更多》

熱點(diǎn)