問題描述
都說https是在http和tcp兩層之間加密,針對的是傳輸過程,只有客戶端和服務端才能解密,變成明文。但是又有很多人說,https協議下,用get請求不加密,需要用post才會加密,而且這么說的人很多。
我的疑惑就是,如果把整個數據都加密了,是不是無論get和post都是一樣的?
因為不懂抓包技術,所以比較好奇。https傳輸下,抓包者抓到的都是亂碼? 能抓到URL,或者header之類的信息嘛?
再補充一個問題,網上還有一種中間人抓包模式?
如果有人在我和服務器之間抓包,偽造證書,搞這個中間人模式,那么瀏覽器是不是直接提示證書不安全?
如果瀏覽器也分辨不出來的話,是不是ssl證書質量不過關?
如果ssl證書質量過關,瀏覽器還無法分辨的話,那https豈不是一點用沒有?該抓還抓,該截還截?
正文
首先直接說結論,https安全通信模式,是使用TLS加密傳輸所有的http協議。再重復一遍,是所有!
通常將TLS加密傳輸http這個通信過程稱為https,如果使用協議封裝的邏輯結構來表達就是:
IP + TCP + TLS +【HTTP】
其中用【】括起來的http是完全被加密保護起來的。
既然http被完全加密起來了,那使用https加密傳輸信息,途徑互聯網的時候,互聯網上的第三方可以知道我們在訪問什么網站嗎?
可以的!
你可能會很驚奇,既然http已經被完全加密了,怎么第三方還會知道我們訪問什么網站?
我們在訪問一個網站時,比如www.zhihu.com,首先會使用DNS將網站的域名解析成IP地址,然后才可以使用IP地址來網站建立TCP連接、TLS安全連接。由于DNS是不加密的,所以第三方只要通過讀取明文的DNS查詢與響應報文,就可以知道我們再訪問哪些網站。
讀者會心生一計,如果我將域名與IP地址的對應關系,保存在本地的host文件里,那么下次就不需要發送DNS查詢報文了,那么第三方就無法知道我們在訪問什么網站了,對嗎?
好主意!
但是第三方可以通過服務器的IP地址,使用DNS反向解析得到服務器的域名。
像知乎這樣的網站通常會使用邊緣加速,一個邊緣加速服務器IP地址會host成千上百個網站,使用DNS反向解析會返回上千個域名,對嗎?
對的!
但是我們與服務器TLS握手時,會在Client Hello報文的“TLS Extension”里攜帶一個明文的“Server Name Indication”用于指示邊緣服務器我們真正要訪問哪個網站,第三方讀取一下SNI就會得到答案。
即使我們的瀏覽器有點古老,不支持SNI擴展,第三方就沒有辦法知道我們訪問哪個網站了?
當然可以知道,因為TLS握手時,服務器推送過來的Server Hello里會攜帶明文的證書,證書里會清清楚楚地標明客戶端正要訪問什么網站。
現在互聯網上大體有以下三種通信模式:
- 不安全通信
- 不完全安全通信
- 安全通信
對于不安全通信、安全通信其實非常好理解,它們分別對應http與https。
http的協議封裝的邏輯架構是這個樣子的:
IP + TCP + HTTP
https的協議封裝的邏輯架構是這樣的:
IP + TCP + TLS +【HTTP】
兩者都使用http協議通信,只是由于后者有TLS的撐腰(安全加密),才使得https通信安全。
不完全安全通信又代表什么呢?
https+ http
讀者會很納悶,如下圖所示,訪問微信公眾平臺明明使用https://的協議前綴(Prefix),應該全部使用https完全安全通信,而不會使用https+ http混合通信,對嗎?
理論上是這樣的,但現實有時卻偏離理論。理想是豐滿的,現實卻是骨感的。
當我們使用https訪問https://www.example.com時,服務器返回的內容是https加密的,這一點問題沒有,當瀏覽器準備顯示的時候,發現要顯示的內容是一個鏈接資源,而這個資源的鏈接地址是:http:// www.example.com,于是瀏覽器使用不加密的http,去訪問服務器,將鏈接所對應的資源拉下來,然后顯示在瀏覽器上。
最終,我們看到的頁面由兩部分組成:https的安全頁面 + http的不安全頁面,我們稱之為混合頁面(Mixed Content)。
為何會產生混合頁面?
最早的服務器提供的是http服務,很多資源的鏈接地址無意中使用了絕對路徑,比如“http:// www.example.com”,在這個絕對路徑中,不僅僅包含了路徑“www.example.com/*****”,同時還包含了訪問協議類型“http”。
這種絕對路徑在http通信用的好好的,用于指示瀏覽器使用TCP 80端口訪問服務器。
當https慢慢成為主流通信方式,越來越多的公司開始從http向https的遷徙,很多服務器跑在了有TLS保護的443端口。
當我們訪問“https:// www.example.com”,瀏覽器可以協議前綴,準確地知道我們要訪問的是服務器的443端口。
一旦鏈接使用絕對路徑,瀏覽器就會乖乖地使用“http://www.example.com/*****”訪問服務器的80端口。
如何解決混合頁面問題?
將所有鏈接的絕對路徑改寫為相對路徑“//www.example.com/*****”。
如果瀏覽器使用https訪問服務器,會默認添加成“https: //www.example.com/*****”。
如果瀏覽器使用http訪問服務器,會默認添加成“http: //www.example.com/*****”。
當你意識到自己訪問的頁面有一部分是明文傳輸時,會否大吃一斤?
混合頁面的存在,網站的owner肯定是知道的,甚至故意將一部分靜態頁面(圖片、視頻、音頻)使用http傳輸,以減輕服務器處理加密報文的負擔。
有潛在的讀取瀏覽器cookie的動態頁面(JAVAscript),絕對不能使用明文傳輸。
使用完全加密的https通信時,則沒有那么麻煩,所以將網站采用完全https通信是最明智的選擇。
再來回顧上一篇的問題,https會加密所有的http內容,但是當瀏覽器嘗試去拉取不安全(http)鏈接時,此時已經不是安全通信了。當抓包時,就會出現在一堆加密報文中,穿插著不加密的報文,讀完這兩篇文章,希望這個問題不再是問題。