最近,群里一個(gè)剛?cè)肼毜男』镆驗(yàn)橛霉倦娔X訪問(wèn)奇怪的網(wǎng)站,被約談了。他很困惑 —— 訪問(wèn)的都是HTTPS
的網(wǎng)站,公司咋知道他訪問(wèn)了啥?

實(shí)際上,由于網(wǎng)絡(luò)通信有很多層,即使加密通信,仍有很多途徑暴露你的訪問(wèn)地址,比如:
-
DNS
查詢(xún):通常DNS
查詢(xún)是不會(huì)加密的,所以,能看到你DNS
查詢(xún)的觀察者(比如運(yùn)營(yíng)商)是可以推斷出訪問(wèn)的網(wǎng)站 -
IP
地址:如果一個(gè)網(wǎng)站的IP
地址是獨(dú)一無(wú)二的,那么只需看到目標(biāo)IP
地址,就能推斷出用戶(hù)正在訪問(wèn)哪個(gè)網(wǎng)站。當(dāng)然,這種方式對(duì)于多網(wǎng)站共享同一個(gè)IP
地址(比如CDN
)的情況不好使 -
流量分析:當(dāng)訪問(wèn)一些網(wǎng)站的特定頁(yè)面,可能導(dǎo)致特定大小和順序的數(shù)據(jù)包,這種模式可能被用來(lái)識(shí)別訪問(wèn)的網(wǎng)站
-
cookies
或其他存儲(chǔ):如果你的瀏覽器有某個(gè)網(wǎng)站的cookies
,顯然這代表你曾訪問(wèn)過(guò)該網(wǎng)站,其他存儲(chǔ)信息(比如localStorage
)同理
除此之外,還有很多方式可以直接、間接知道你的網(wǎng)站訪問(wèn)情況。
本文將聚焦在HTTPS
協(xié)議本身,聊聊只考慮HTTPS
協(xié)議的情況下,你的隱私是如何泄露的。
HTTPS簡(jiǎn)介
我們每天訪問(wèn)的網(wǎng)站大部分是基于HTTPS
協(xié)議的,簡(jiǎn)單來(lái)說(shuō),HTTPS
= HTTP
+ TLS
,其中:
-
HTTP
是一種應(yīng)用層協(xié)議,用于在互聯(lián)網(wǎng)上傳輸超文本(比如網(wǎng)頁(yè)內(nèi)容)。由于HTTP
是明文傳遞,所以并不安全 -
TLS
是一種安全協(xié)議。TLS
在傳輸層對(duì)數(shù)據(jù)進(jìn)行加密,確保任何敏感信息在兩端(比如客戶(hù)端和服務(wù)器)之間安全傳輸,不被第三方竊取或篡改
所以理論上,結(jié)合了HTTP
和TLS
特性的HTTPS
,在數(shù)據(jù)傳輸過(guò)程是被加密的。但是,TLS
建立連接的過(guò)程卻不一定是加密的。
TLS的握手機(jī)制
當(dāng)我們通過(guò)TLS
傳遞加密的HTTP
信息之前,需要先建立TLS
連接,比如:
-
當(dāng)用戶(hù)首次訪問(wèn)一個(gè)
HTTPS
網(wǎng)站,瀏覽器開(kāi)始查詢(xún)網(wǎng)站服務(wù)器時(shí),會(huì)發(fā)生TLS
連接 -
當(dāng)頁(yè)面請(qǐng)求
API
時(shí),會(huì)發(fā)生TLS
連接
建立連接的過(guò)程被稱(chēng)為「TLS握手」,根據(jù)TLS
版本不同,握手的步驟會(huì)有所區(qū)別。

但總體來(lái)說(shuō),「TLS握手」是為了達(dá)到三個(gè)目的:
-
協(xié)商協(xié)議和加密套件:通信的兩端確認(rèn)接下來(lái)使用的
TLS
版本及加密套件 -
驗(yàn)證省份:為了防止“中間人”攻擊,握手過(guò)程中,服務(wù)器會(huì)向客戶(hù)端發(fā)送其證書(shū),包含服務(wù)器公鑰和證書(shū)授權(quán)中心(即
CA
)簽名的身份信息。客戶(hù)端可以使用這些信息驗(yàn)證服務(wù)器的身份 -
生成會(huì)話密鑰:生成用于「加密接下來(lái)數(shù)據(jù)傳輸」的密鑰
TLS握手機(jī)制的缺點(diǎn)
雖然TLS
握手機(jī)制會(huì)建立安全的通信,但在握手初期,數(shù)據(jù)卻是明文發(fā)送的,這就造成「隱私泄漏」的風(fēng)險(xiǎn)。
在握手初期,客戶(hù)端、服務(wù)端會(huì)依次發(fā)送、接收對(duì)方的「打招呼信息」。首先,客戶(hù)端會(huì)向服務(wù)端打招呼(發(fā)送「client hello信息」),該消息包含:
-
客戶(hù)端支持的
TLS
版本 -
支持的加密套件
-
一串稱(chēng)為「客戶(hù)端隨機(jī)數(shù)」(
client random
)的隨機(jī)字節(jié) -
SNI
等一些服務(wù)器信息
服務(wù)端接收到上述消息后,會(huì)向客戶(hù)端打招呼(發(fā)送「server hello消息」),再回傳一些信息。
其中,SNI
(Server Name Indication
,服務(wù)器名稱(chēng)指示)就包含了用戶(hù)訪問(wèn)的網(wǎng)站域名。
那么,握手過(guò)程為什么要包含SNI
呢?
這是因?yàn)椋?dāng)多個(gè)網(wǎng)站托管在一臺(tái)服務(wù)器上并共享一個(gè)IP
地址,且每個(gè)網(wǎng)站都有自己的SSL
證書(shū)時(shí),那就沒(méi)法通過(guò)IP
地址判斷客戶(hù)端是想和哪個(gè)網(wǎng)站建立TLS
連接,此時(shí)就需要「域名信息」輔助判斷。
打個(gè)比方,快遞員送貨上門(mén)時(shí),如果快遞單只有收貨的小區(qū)地址(IP
地址),沒(méi)有具體的門(mén)牌號(hào)(域名),那就沒(méi)法將快遞送到正確的客戶(hù)手上(與正確的網(wǎng)站建立TLS
連接)。
所以,SNI
作為TLS
的擴(kuò)展,會(huì)在TLS
握手時(shí)附帶上域名信息。由于打招呼的過(guò)程是明文發(fā)送的,所以在建立HTTPS
連接的過(guò)程中,中間人就能知道你訪問(wèn)的域名信息。
企業(yè)內(nèi)部防火墻的訪問(wèn)控制和安全策略,就是通過(guò)分析SNI
信息完成的。
雖然防火墻可能已經(jīng)有授信的證書(shū),但可以先分析
SNI
,根據(jù)域名情況再判斷要不要進(jìn)行深度檢查,而不是對(duì)所有流量都進(jìn)行深度檢查
那么,這種情況下該如何保護(hù)個(gè)人隱私呢?
Encrypted ClientHello
Encrypted ClientHello[1](ECH
)是TLS
1.3的一個(gè)擴(kuò)展,用于加密Client Hello
消息中的SNI
等信息。
當(dāng)用戶(hù)訪問(wèn)一個(gè)啟用ECH
的服務(wù)器時(shí),網(wǎng)管無(wú)法通過(guò)觀察SNI
來(lái)窺探域名信息。只有目標(biāo)服務(wù)器才能解密ECH
中的SNI
,從而保護(hù)了用戶(hù)的隱私。
當(dāng)然,對(duì)于授信的防火墻還是不行,但可以增加檢查的成本
開(kāi)啟ECH
需要同時(shí)滿足:
-
服務(wù)器支持
TLS
的ECH
擴(kuò)展 -
客戶(hù)端支持
ECH
比如,cloudflare SNI測(cè)試頁(yè)[2]支持ECH
擴(kuò)展,當(dāng)你的瀏覽器不支持ECH
時(shí),訪問(wèn)該網(wǎng)站sni
會(huì)返回plAIntext
:

對(duì)于chrome
,在chrome://flags/#encrypted-client-hello[3]中,配置ECH
支持:

再訪問(wèn)上述網(wǎng)站,sni
如果返回encrypted
則代表支持ECH
。
總結(jié)
雖然HTTPS
連接本身是加密的,但在建立HTTPS
的過(guò)程中(TLS
握手),是有數(shù)據(jù)明文傳輸?shù)模渲?code>SNI中包含了服務(wù)器的域名信息。
雖然SNI
信息的本意是解決「同一IP下部署多個(gè)網(wǎng)站,每個(gè)網(wǎng)站對(duì)應(yīng)不同的SSL證書(shū)」,但也會(huì)泄漏「訪問(wèn)的網(wǎng)站地址」。
ECH
通過(guò)對(duì)TLS
握手過(guò)程中的敏感信息(主要是SNI
)進(jìn)行加密,為用戶(hù)提供了更強(qiáng)的隱私保護(hù)。
參考資料
[2]cloudflare SNI測(cè)試頁(yè):https://crypto.cloudflare.com/cdn-cgi/trace
[3]chrome://flags/#encrypted-client-hello:chrome://flags/#encrypted-client-hello