最近,群里一個剛入職的小伙因為用公司電腦訪問奇怪的網站,被約談了。他很困惑 —— 訪問的都是HTTPS
的網站,公司咋知道他訪問了啥?

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

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

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

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