隨着用戶安全意識的加強,近兩年網絡協議已逐步從Http協議向Https協議開始過分,目前大多數APP/Web都開始使用Https協議,這裏以Http逐步發展成Https協議的過程爲導向,介紹Https的誕生過程。html
通訊使用明文意味着安全性大大下降,當通訊過程被竊聽後,無需花費額外的投入就可看到傳輸的數據。例如使用抓包工具,無需任何配置就可查看任何使用HTTP協議的通訊數據;linux
不驗證通訊方的身份,將致使通訊過程被竊聽後,可能會遭遇假裝,例如使用抓包工具抓取數據後,就可按照數據包的格式構造HTTP請求;算法
不驗證報文的完整性,數據在傳輸過程當中就可能被篡改,原本想看喜洋洋呢,結果數據在傳輸過程當中被換成了光頭強。編程
既然明文不安全,那能夠考慮使用密文,即:對通訊數據進行加密。即使數據被竊聽,對方依然須要花費必定的投入來破解,這種高昂的成本間接提升了安全級別。安全
和服務端使用相同的算法,根據網絡請求參數生成一個token,請求/應答時根據token來肯定雙方的身份。服務器
使用MD5/SHA1等算法進行完整性驗證, 對方接收到數據後,根據一樣的算法生成散列值,比對發送方生成的散列值,便可驗證數據的完整性。 解決了HTTP的以上問題,HTTPS協議就誕生了:網絡
Https = Http + 加密 + 認證 + 完整性驗證
複製代碼
而對於加密,認證和完整性驗證這些特色,TCP/IP協議族中已經提供了一個用於數據安全傳輸的協議——SSL(Secure Socket Layer)安全套接層,雖然也是基於TCP實現的,但SSL並非應用層協議,而是一個位於應用層與傳輸層之間的協議,(具體協議相關的理論知識可參考網絡編程之理論知識。)其目的就是爲上層的應用層協議提供安全的傳輸通道。這時Https協議就可用如下形式表示:併發
Https = Http + SSL
複製代碼
這樣看來,HTTPS並非一個單獨的應用層協議,而只是Http使用SSL通道進行數據傳輸的過程。那麼對於Https, 只須要了解Http(參考HTTP詳解)和SSL協議便可。而所謂的HTTPS報文也就是SSL報文: dom
SSL(Secure Socket Layer)安全套接層,是一種位於應用層與傳輸層之間,爲網絡通訊提供安全及完整性驗證的一種網絡協議。工具
相對於TCP或HTTP協議,SSL協議要複雜不少。因爲它也是創建在TCP協議之上的,因此在使用SSL傳輸數據以前須要先進行三次握手和服務器創建鏈接,具體的流程如圖所示:
前兩步是協商加密算法以及傳輸各自生成的隨機數(爲後續生成master secret作準備)的過程;
第三步服務端將本身的證書發送給客戶端,這個證書中包含一個數字簽名(CA簽名)和服務端CA證書的公鑰,客戶端對證書中包含的服務端信息進行Hash, 同時使用接收到的公鑰對數字證書解密,獲取其中的Hash值,與前面計算獲得的Hash值進行比較,便可驗證證書的有效性(完整性&真實性);
服務端收到客戶端發送的Change Cipher Spec(第五步),會使用本身的私鑰進行解密,獲取報文中的Pre-master secret,這時通訊雙方都擁有對方的Random(前兩步生成的),Pre-master secret,以及自身的Random, 將三個數做爲種子經過算法生成master secret, 用來加密後續Http請求過程當中的數據。其中master secret的生成規則爲:
master_secret = MD5(pre_master_secret + SHA('A' + pre_master_secret + ClientHello.random + ServerHello.random)) + MD5(pre_master_secret + SHA('BB' + pre_master_secret + ClientHello.random + ServerHello.random)) + MD5(pre_master_secret + SHA('CCC' + pre_master_secret + ClientHello.random + ServerHello.random));
更詳細的有關SSL協議的內容可參考:RFC 6101 SSL
兩個方面的考量:安全,效率。若是直接使用對稱加密的方式進行加密,若是密鑰不被泄漏固然也是安全,但問題是:密鑰如何傳遞給另外一端呢,在數據傳輸過程當中,若是通訊被竊聽,則密鑰被竊取,那此時加密就沒有任何意義了。那可不可使用非對稱加密的方式呢?理論上是能夠的,數據傳輸以前,服務端只須要將本身的公鑰傳輸給客戶端,客戶端在傳輸數據時,使用接收的公鑰進行加密,服務端接收到數據後使用私鑰進行解密便可。但這裏有個不容忽視的問題:效率。非對稱加密須要大量計算,確定會佔用不少硬件資源,因此效率過低。因此爲了解決安全和效率問題,SSL使用了對稱加密(加密和解密使用一樣的密鑰)和非對稱加密(公鑰加密,私鑰解密)組合的方式:使用非對稱加密的方式傳輸對稱加密中生成密鑰的種子(pre master secret)【對應上面的第五步】,而後使用對稱加密的方式對通訊數據進行加密【對應上面的第十步】,既保障了密鑰的安全性,也提升了加密速度。
既然Https那麼安全,那爲何用抓包工具仍是能夠看到裏面的數據。這裏須要對抓包過程的原理作一個簡單的介紹,抓包,其實就是中間人攻擊,在網絡請求過程當中,抓包工具充當着客戶端/服務端的角色,當客戶端請求數據時,抓包工具將請求進行攔截,而後構造數據(冒充客戶端)向服務端發起請求,此時服務端會返回本身的公鑰證書,而後抓包工具將服務端的公鑰證書替換成本身的公鑰證書,隨後將數據返回可客戶端(此時充當服務端的角色)。客戶端拿到公鑰證書後,使用公鑰證書中的公鑰對Pre-master secret進行加密,併發送給服務端,發送過程當中又被抓包工具攔截,因爲客戶端使用的公鑰其實就是抓包工具生成的證書公鑰,因此抓包工具只須要使用本身的私鑰進行解密便可拿到真實的Pre-master secret(由於抓包工具在以前的過程當中已經拿到了雙方的隨機碼,因此到這一步抓包工具至關於已經拿到了後續通訊使用的密鑰),隨後抓包工具使用從服務端接收到的公鑰證書中的公鑰對Pre-master secret進行加密,而後發送給服務端。隨後的通訊過程雖然進行了加密,但抓包工具已經生成了密鑰(master secret),因此能夠查看Https的通訊內容。一圖以蔽之:
從抓包的原理能夠看出,對Https進行抓包,須要PC端和手機端同時安裝證書。
既然這麼容易被抓包,那Https會不會顯得很雞肋?其實並不會,能抓包,那是由於你信任抓包工具,手機上安裝了與之對應的證書,你要不安裝證書,你抓一個試試。並且安全這個課題,是在攻防中求發展,沒有最安全,只有更安全,因此將攻擊的成本提升了,就間接達到了安全的目標。
這裏以Charles4.0爲例,對Https進行抓包:
既然使用了Https協議,就是不想讓別人看到數據,那如何避免被抓包呢?這裏有2種方法可參考:
使用自定義協議,也就是以TCP/UDP爲基礎,使用Socket進行通訊(具體可參考網絡編程之理論篇),這種方式因爲不是使用的Http/Https協議,因此可避免Http類型的抓包工具(如Charles, Fiddler)進行抓包, 但不可避免WireShark,畢竟它太強大,可抓取網絡模型中各層的數據。
看着很陌生,其實也不是啥新技術,只須要將服務端的公鑰證書一塊兒打到APK中,在網絡請求時,與服務端的公鑰證書進行比較,便可避免抓包工具使用構造證書進行抓包的狀況。
以上即是整個Http過渡到Https的過程,這種以協議發展爲導向的方式,可能更有助於理解。固然,這只是我的對Https協議的理解,若有不恰當之處,歡迎指正。
圖解HTTP