隨著用戶安全意識的增強,近兩年網絡協議已逐步從Http協議向Https協議開始過度,目前大多數APP/Web都開始使用Https協議,這里以Http逐步發展成Https協議的過程為導向,介紹Https的誕生過程。
對于加密,認證和完整性驗證這些特點,TCP/IP協議族中已經提供了一個用于數據安全傳輸的協議——SSL(Secure Socket Layer)安全套接層,雖然也是基于TCP實現的,但SSL并不是應用層協議,而是一個位于應用層與傳輸層之間的協議,其目的就是為上層的應用層協議提供安全的傳輸通道。這時Https協議就可用以下形式表示:
```
Https = Http + SSL
```
這樣看來,HTTPS并不是一個單獨的應用層協議,而只是Http使用SSL通道進行數據傳輸的過程。那么對于Https, 只需要了解Http和SSL協議即可。而所謂的HTTPS報文也就是SSL報文:

### SSL協議
[SSL](Secure Socket Layer)安全套接層,是一種位于應用層與傳輸層之間,為網絡通信提供安全及完整性驗證的一種網絡協議。
相對于TCP或HTTP協議,SSL協議要復雜很多。由于它也是建立在TCP協議之上的,所以在使用SSL傳輸數據之前需要先進行三次握手和服務器建立連接,具體的流程如圖所示:

具體的加密流程:

#### SSL協議的握手過程
1. 客戶端先給服務端發送一個消息,消息內容包括:客戶端支持的加密方式,支持的壓縮方法,SSL的版本號,客戶端生成的隨機數,文本內容“Hello”等;
2. 服務端接收到消息后,也回發一個Hello,并攜帶從客戶端支持的加密方式中選擇的加密方式,服務端生成的隨機數,服務端的SSL版本號等信息;
3. 隨后服務器給客戶端發送一個Certificate報文,報文中包含服務端的公鑰證書;
4. 緊接著服務器給客戶端發送Server Hello Done, 表示最初的協商握手過程結束;
5. 客戶端接收到服務端發送的握手結束的消息后,以Client Key Exchange作為回應,此報文中包含通信加密過程中使用的一種被稱為Pre-master secret的隨機密碼串,并使用第三步接收到的公鑰證書進行了加密;
6. 接著客戶端發送Change Cipher Spec報文,該報文告知服務端,此步驟之后的所有數據將使用第五步中生成的master secret進行加密(master secret的生成過程看后面的介紹);
7. 隨后客戶端發送Finish報文,此報文中包含連接至今所有報文的整體校驗值,用于完整性驗證;
8. 服務端接收到客戶端發送的Change Cliper Spec報文后,同樣以Change Cliper Spec報文作為回應;
9. 接著服務端發送Finish報文給客戶端,表示服務端已正確解析客戶端發送的整體校驗值,至此,SSL握手的過程結束。
10. 隨后開始使用HTTP協議傳輸使用master secret加密過的數據。
##### 說明
* 前兩步是協商加密算法以及傳輸各自生成的隨機數(為后續生成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));
* 客戶端生成一個隨機數?`random-client`,傳到服務器端(Say Hello)
* 服務器端生成一個隨機數?`random-server`,和著公鑰,一起回饋給客戶端(I got it)
* 客戶端收到的東西原封不動,加上?`premaster secret`(通過?`random-client`、`random-server`?經過一定算法生成的東西),再一次送給服務器端,這次傳過去的東西會使用公鑰加密
* 服務器端先使用私鑰解密,拿到?`premaster secret`,此時客戶端和服務器端都擁有了三個要素:`random-client`、`random-server`?和?`premaster secret`
* 此時安全通道已經建立,以后的交流都會校檢上面的三個要素通過算法算出的?`session key`
## 為什么要這么干
兩個方面的考量:安全,效率。如果直接使用對稱加密的方式進行加密,如果密鑰不被泄漏當然也是安全,但問題是:密鑰如何傳遞給另一端呢,在數據傳輸過程中,如果通信被竊聽,則密鑰被竊取,那此時加密就沒有任何意義了。那可不可以使用非對稱加密的方式呢?理論上是可以的,數據傳輸之前,服務端只需要將自己的公鑰傳輸給客戶端,客戶端在傳輸數據時,使用接收的公鑰進行加密,服務端接收到數據后使用私鑰進行解密即可。但這里有個不容忽視的問題:效率。非對稱加密需要大量計算,肯定會占用很多硬件資源,所以效率太低。所以為了解決安全和效率問題,SSL使用了[對稱加密](https://baike.baidu.com/item/%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86/2152944?fr=aladdin)(加密和解密使用同樣的密鑰)和[非對稱加密](https://baike.baidu.com/item/%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86)(公鑰加密,私鑰解密)組合的方式:使用非對稱加密的方式傳輸對稱加密中生成密鑰的種子(pre master secret)【對應上面的第五步】,然后使用對稱加密的方式對通信數據進行加密【對應上面的第十步】,既保障了密鑰的安全性,也提高了加密速度。
### Https絕對安全么
既然Https那么安全,那為什么用抓包工具還是可以看到里面的數據。這里需要對抓包過程的原理做一個簡單的介紹,抓包,其實就是中間人攻擊,在網絡請求過程中,抓包工具充當著客戶端/服務端的角色,當客戶端請求數據時,抓包工具將請求進行攔截,然后構造數據(冒充客戶端)向服務端發起請求,此時服務端會返回自己的公鑰證書,然后抓包工具將服務端的公鑰證書替換成自己的公鑰證書,隨后將數據返回可客戶端(此時充當服務端的角色)。客戶端拿到公鑰證書后,使用公鑰證書中的公鑰對Pre-master secret進行加密,并發送給服務端,發送過程中又被抓包工具攔截,由于客戶端使用的公鑰其實就是抓包工具生成的證書公鑰,所以抓包工具只需要使用自己的私鑰進行解密即可拿到真實的Pre-master secret(因為抓包工具在之前的過程中已經拿到了雙方的隨機碼,所以到這一步抓包工具相當于已經拿到了后續通信使用的密鑰),隨后抓包工具使用從服務端接收到的公鑰證書中的公鑰對Pre-master secret進行加密,然后發送給服務端。隨后的通信過程雖然進行了加密,但抓包工具已經生成了密鑰(master secret),所以可以查看Https的通信內容。一圖以蔽之:

從抓包的原理可以看出,對Https進行抓包,需要PC端和手機端同時安裝證書。
既然這么容易被抓包,那Https會不會顯得很雞肋?其實并不會,能抓包,那是因為你信任抓包工具,手機上安裝了與之對應的證書,你要不安裝證書,你抓一個試試。而且安全這個課題,是在攻防中求發展,沒有最安全,只有更安全,所以將攻擊的成本提高了,就間接達到了安全的目標。
### 如何對Https進行抓包
這里以Charles4.0為例,對Https進行抓包:
1. 依次點擊菜單Help -> SSL Proxying -> Install Charles Root Certificate安裝PC證書;
2. 依次點擊菜單Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device or Romote Browser, 此時會彈出一個框,提示讓你去 chls.pro/ssl 去下載證書,下載完成后進行安裝即可;
3. 依次點擊菜單Proxy -> SSL Proxying Settings, 選中頁面中的Enable SSL Proxying, 然后點擊下面的add, 在彈出的框中的Host編輯框中填寫\*.\* (表示可對所有Https請求進行抓包),端口填寫443,點擊OK;
4. 手機設置代理(你的電腦的IP地址,端口默認為8888)即可進行抓包;
## 參考資料:
> https://juejin.cn/post/6844903602494898183#heading-9