轉(zhuǎn)載
http://blog.csdn.net/sara_xuehua/article/details/73331981
原作者說的形象生動,贊~
原文
最近因工作需要,要用 Charles 來監(jiān)聽 HTTPS 的請求,然而好不容易按照網(wǎng)上的文章配置完成之后,卻發(fā)現(xiàn)監(jiān)聽的內(nèi)容居然是一坨亂碼。隨后進行了一個 SSL 代理配置,和手機證書的安裝,才終于獲取到了明文。雖然之前有了解 HTTPS 是使用大素數(shù)收到進行加密,也知道有一次非對稱加密和對稱加密,但是經(jīng)過這次的配置發(fā)現(xiàn)對它的根本原理還不是很了解,于是專門研究了一下,才搞明白它的原委。
Charles HTTPS 代理配置
我們先開宗明義,把問題解決一下:要進行 HTTPS 代理配置,其實只需要兩個步驟:
- 在代理端進行 SSL 代理設(shè)置;
- 在客戶端進行證書安裝。
SSL 代理設(shè)置
在 Charles 設(shè)置 SSL 代理,步驟為:
Proxy –> SSL Proxying Setting –> Enable SSL Proxying
之后便會看到下面的選框:

點擊 Add,編輯 Loction,按照如下填寫:

一路點 OK,這第一步就這樣成了。
客戶端證書安裝
PC 端證書安裝
假如代理的是 PC 端的 HTTPS 請求,需要在 PC 上信任 Charles 的證書,步驟為:
Help –> SSL Proxying –> Install Charles Root Certificate
選擇 Charles 的證書,并信任此證書:

手機端證書安裝
在移動端安裝證書,步驟為:
Help –> SSL Proxying –>Install Charles Root Certificate on a Mobile Device
之后會彈出這樣一個對話框:

按照上面的要求,在手機上配置好端口為 8888 的代理之后,訪問 http://chls.pro/ssl就可以下載證書并安裝了。
實際上做完這兩部,就可以在你的 PC 和移動設(shè)備上愉快的進行 HTTPS 的代理,并獲取明文內(nèi)容了(具體如何解決問題,也可以參考這篇文章);盡管到這一步就已經(jīng)達到了實際使用的效果,但我還是產(chǎn)生了這樣的疑問:為何進行 HTTPS 代理的配置需要配置 SSL,以及在客戶端安裝證書呢?之前截獲的內(nèi)容又為什么是亂碼呢?
亂碼的緣由 —— SSL 加密
其實稍微對 HTTPS 有點認知的童鞋,一開始就不應(yīng)該對 HTTPS 截取的內(nèi)容是亂碼而感動吃驚:喵的這可是 HTTPS 啊,一個代理就能竊聽到獲明文內(nèi)容,那也毫無安全性可言了吧。
那 HTTPS 到底是利用什么原理進行加密的呢?我們可以看到,上面的步驟中,配置 Charles 的第一步就是先配置一個 SSL 代理,實際上 HTTPS 的那個 S 也可以翻譯為 HTTP over SSL/TLS,這個 SSL 正是 HTTP 加密依賴的基礎(chǔ)協(xié)議。
SSL/TLS 是傳輸層安全協(xié)議,與其他應(yīng)用層協(xié)議(如 HTTP/FTP 等)獨立無關(guān),也就是說,在應(yīng)用層協(xié)議開始通信之前,SSL/TLS 協(xié)議就已經(jīng)完成了相關(guān)的加密工作,后續(xù)協(xié)議傳輸?shù)膬?nèi)容已經(jīng)是加密數(shù)據(jù)了。所以其實 HTTP 還是那個 HTTP,但傳輸?shù)膬?nèi)容早已變成天書,這也就是我們在用 Charles 進行代理的時候,看到一堆亂碼的原因。
不過快播的審判員說的好:『文件加密了,你為什么不解密呢?』是啊,為什么經(jīng)過 SSL/TLS 協(xié)議處理過的內(nèi)容,不能夠被解密呢?這里就涉及到 SSL 協(xié)議的基本原理,我們用寫信,來模擬一下這個加密的過程:
- 小明和小王是一對好基友,但是遠隔萬水千山,只能通過寫信來傳遞消息。倆人每天的信件都是通過郵遞員小紅來傳遞的,這倆人每天紙條上明文寫著信息,小紅也天天看的不亦樂乎,這就是 HTTP。
- 時間久了,兩人發(fā)現(xiàn)不行,比如有時候會傳遞一些不和諧的內(nèi)容,不希望小紅這樣的腐女看到;于是小明靈機一動,換成葬愛家族的殺馬特火星文來進行通信;小王看后,心領(lǐng)神會。由于轉(zhuǎn)換方式兩人都知道,這就是對稱加密技術(shù)。
- 然而好景不長,小紅勤學(xué)苦練,終于練成了火星文十級,又能看懂倆人加密的內(nèi)容了。倆人必須要更換加密方式,但是更換的加密方式也只能通過小紅來傳遞,所以這個加密的手段很難瞞住小紅,這就是 HTTP 的不安全性。
- 正好小明是一位博學(xué)的哲♂學(xué)家,他立刻寫了封信給小王:把你家儲物間箱子的上那把掛鎖寄過來!小王看后立刻拿出了那把 82 年的掛鎖,把它打開并寄給了小明。這個鎖大家都能看到,但只有小王有鑰匙,這就是傳說中的非對稱加密,鎖就是公鑰,小王的鑰匙就是私鑰。
- 小明收到后,仔細研究了那把鎖,上面燙著『隔壁老王』四個鎏金大字,正是王家祖?zhèn)鞯逆i,這就是驗證服務(wù)端的數(shù)字證書。
- 于是小明放心的把新的加密方式寫在信中,放到盒子里,然后用鎖鎖上。由于小紅沒有鑰匙,沒法查看盒子里到底寫了啥,只能原樣送過去。小王收到后,用自己的鑰匙打開了鎖,獲得了新的加密方式。這就完成了 SSL 協(xié)議的握手。
當然,上面的過程描述的非常粗糙,小明和小王在互相寄鎖的時候,還需傳遞隨機數(shù)來輔助生產(chǎn)最終的加密方式(也是一個隨機數(shù),稱之為 Premaster secret);有興趣的兄貴們可以看看文末的參考文章。
Charles 的破解之道
那么問題就來了:Charles 作為一只小紅,是怎么破解上述加密通信的呢?莫非她大力出奇跡,直接砸了鎖?我們知道,要砸鎖是不太現(xiàn)實的,這等于要對大素數(shù)的乘積進行因式分解,現(xiàn)階段下還做不到;因此 Charles 就做了一件最簡單的事情:偽裝成小明(也就是中間人攻擊)。
Charles 的官網(wǎng)上是這么說的:
Charles 作為一個中間人來進行 HTTPS 的代理,讓我們檢測到瀏覽器和 SSL web 服務(wù)端之間的明文通信。
Charles 把自己變成一個中間人來達到這一目的。你的瀏覽器是收不到服務(wù)端證書的,Charles 會用自己的根證書動態(tài)簽發(fā)一張證書,然后 Charles 來接受服務(wù)端的證書,你的瀏覽器接受 Charles 的證書。
…
Charles 仍然通過 SSL 與服務(wù)端進行通信,但通信是通過瀏覽器到 Charles,然后在從 Charles 到服務(wù)器。
那么上文所說的根證書與動態(tài)簽發(fā)證書,指的是什么意思呢?這里就說到了證書的信任鏈體系,這是一個樹狀的結(jié)構(gòu),全球有為數(shù)不多的根證書頒發(fā)機構(gòu),授權(quán)二級證書頒發(fā)機構(gòu)進行證書頒發(fā);而只要用戶信任了根證書,就會對其下屬二級機構(gòu)頒發(fā)的所有證書都予以信任。

上圖可以看到 VeriSign 就是根證書頒發(fā)機構(gòu),而知乎的證書是由其二級證書頒發(fā)機構(gòu)頒發(fā)的。由于操作系統(tǒng)里內(nèi)置了對 VeriSign 的授信,因此知乎的地址欄才能有一把綠色的小鎖。
因此 Charles 如果想對所有的域名頒發(fā)證書,必須要有一個根證書;用戶信任了這個根證書,所有走 Charles 代理的 HTTPS 就都能被竊聽了。
我們在用小紅為例,復(fù)現(xiàn)一下這個場景:
- 小紅拿到鎖以后,先扣著不發(fā),然后掏出了自己的鎖寄給小明,這就是 Charles 簽發(fā)了自己根證書;
- 小明一看這把鎖不是正宗王家的,但是小紅家的鎖,似乎也可以相信,這就是信任了 Charles 的根證書;
- 小明把加密方式寫進去,然后用小紅的鎖鎖起來了,小紅打開之后研究了加密方式,發(fā)現(xiàn)兩人是在用水星文進行交流,瞬間水星文也達到了十級,然后在換上小王的鎖鎖上了盒子,還給了小王;
- 小王毫不知情,之后倆人用水星文進行交流,但內(nèi)容已經(jīng)全被小紅捕獲到了。
搞明白這些之后,我們再來看一下,為什么要進行 Charles 的那兩個配置呢?
- 設(shè)置 SSL 代理:因為默認 HTTP 請求走的是 80 端口,HTTPS 請求走的是 443 端口,不設(shè)置的話 Charles 僅會默認更改系統(tǒng)的 HTTP 代理,只有 HTTP 流量會走 Charles,而設(shè)置這個 HTTPS 的流量才會從這兒走;
- 安裝 Charles 的根證書:根據(jù)信任鏈,只要安裝一下 Charles 的根證書,之后 Charles 頒發(fā)的所有域名的證書都能被自動信任,因此 HTTPS 就都能被竊聽了。
把證書的信任鏈翻譯到鎖上,等于小明會預(yù)先信任幾個大廠生產(chǎn)的鎖,比如只要是老王牌的鎖,那我都相信,其他人也可以用這類鎖來跟我要加密方式;Charles 等于創(chuàng)造了一個小紅五金廠,把所有代理的請求都掛上了小紅鎖。那么 12306 其實跟小紅一樣,由于某些原因沒有大廠申請一個鎖,而是自己開了一個老鐵五金廠,然后跟用戶說:『相信我鐵道部的老鐵五金廠的鎖吧,不然你就憋想回家!』
用戶還能怎么辦?只能含著淚點確認:『老鐵,沒毛??!』