前言
因爲工作需要,需要用到大量的關於 HTTP 協議的知識,目前掌握的關於 HTTP 請求以及協議的知識都是零散的,打算針對知識盲區系統的學習一些,理清概念。
爲什麼會出現 HTTPS
因爲 HTTP 存在一些難以解決的問題,以下是安全性的問題,這促使產生了 HTTPS。HTTP 在安全性方面,主要有以下的問題。
- HTTP 採用明文傳輸,內容可能會被竊聽
- HTTP 不驗證對方的身份,可能會遭遇僞裝
- HTTP 不驗證內容的完整性,可能會遭遇篡改
既然又了上述問題,那麼顯然 HTTPS 就是要來解決這些問題。
HTTP + 加密 + 認證 + 完整性驗證 = HTTPS
簡介
從標題可以看出來,額外添加的功能,實際上正好對應上述 HTTP 所存在的問題,將他們逐個解決就形成了 HTTPS。
這裏想先介紹兩個概念。
- SSL:Secure Socket Layer 安全套接層, 最初是由網景公司(Netscape)研發,因爲發現 HTTP 存在安全性問題。後被IETF(The Internet Engineering Task Force - 互聯網工程任務組)標準化後寫入(RFCRequest For Comments),RFC裏包含了很多互聯網技術的規範。
- TLS:由於HTTPS的推出受到了很多人的歡迎,在SSL更新到3.0時,IETF對SSL3.0進行了標準化,並添加了少數機制(但是幾乎和SSL3.0無差異),標準化後的IETF更名爲TLS1.0(Transport Layer Security 安全傳輸層協議),可以說TLS就是SSL的新版本3.1,並同時發佈“RFC2246-TLS加密協議詳解”。
這倆段是從網絡上搜索得來的,可以看出來平時所說的 SSL/TLS 其實可以理解成一種加密方式即可,沒必要分開來看,後文就稱之爲 SSL 了。得益於網絡結構的分層設計,很容易在 HTTP 協議下加上一層。HTTP 一般直接和 TCP 進行通信,而 HTTPS 首先要經過 SSL 層,然後再和 TCP 通信。其實我學到這裏的時候,很容易就能想到,有得必有失,HTTPS 增加了安全性,但是同時降低了性能,但是就目前的趨勢來看,安全性肯定更重要,所以往後應該基本上都會採用 HTTPS 的方式吧。
到這裏,可以認爲 HTTPS 相比與 HTTP,多了一層 SSL,用來保證安全性。
- HTTP:HTTP -> TCP
- HTTPS: HTTP -> SSL -> TCP
加密
首先來看看加密,關於加密,就不得不說兩種加密手段,對稱加密和非對稱加密,這兩種方法在 HTTPS 中均有體現。
對稱加密 🔐
在整個過程中之存在一把密鑰,雙方都用這一把密鑰進行加密。舉個例子:A 生成了一把密鑰 e,然後將這個密鑰以一種安全的方式交給 B。隨後,A 利用 e 對信息進行加密並傳輸給 B,B 利用 e 進行解密,然後同樣的用 e 加密信息傳遞給 A。
這就是對稱加密的過程,其中存在一些問題。A 如何將密鑰 e 安全的傳輸給 B ?如果傳輸過程中密鑰 e 被人竊取,那麼隨後的通信都是不安全的。
非對稱加密 🔐
非對稱加密過程中會存在兩把密鑰,一把爲公開密鑰,一把爲私有密鑰,用一把密鑰進行加密的信息,只能用另一把密鑰進行解密。公開密鑰可以發送給其他人,其他人使用公開密鑰對信息加密,傳遞給生成密鑰的人,生成密鑰的人用自己的私有密鑰對信息進行解密。舉個例子:A 生成了一對公有和私有的密鑰,私有密鑰自己保管,公有密鑰傳給 B,B 使用 A 的公有密鑰對信息進行加密,傳遞給 A,A 收到信息後使用私有密鑰進行解密。因爲私有密鑰不用傳輸,因此極大的提升了安全性。
當然如果 A 要向 B 傳遞加密信息,也是需要 B 生成一對密鑰,然後 A 持有 B 的公有密鑰,對信息加密後傳遞給 B。
HTTPS 採用的方式
非對稱加密的速度要比對稱加密的速度要慢,如果我們可以安全的傳遞對稱加密中的密鑰,那麼我們是不是就可以只用對稱加密方法了呢?
HTTPS 採用一種混合的方式來處理。先使用非對稱加密的方式傳遞對稱加密方法中的密鑰,隨後的通信採用對稱加密的方式。
認證
現在有了加密階段的工作,HTTP 看起來似乎安全了一些,但是還是有問題,如何將對稱加密中的公有密鑰傳遞給其他人,你怎麼能保證公有密鑰不被篡改、替換等?感覺如果只有兩個人的話,始終無法解決這個問題。這個時候出現了第三方,權威可信的機構(果然,最後還是得靠信任,如果權威可信的機構某天變得不可信了的話,......)
使用由數字證書認證機構(CA,Certificate Authority)和其相關機關頒發的公開密鑰證書,可以很大程度上解決以上的問題。
- 服務器運營方 A,向 CA 提出申請,把公有密鑰登記到 CA。
- CA 用自己的私有密鑰對 A 的公有密鑰簽名,並頒發一個數字證書。
- 客戶端提前內置了可信的 CA 的公有密鑰。
到這裏離線的步驟已經做完了,下面是通信的部分。
- 服務器給客戶端發送公鑰證書
- 客戶端收到證書後,利用 CA 的公鑰對 證書的簽名進行驗證,來判斷服務器的公鑰是否可信。
- 如果可信,則開始後續的通信,也就是“加密”小節 HTTPS 採用的方式。
這裏插一句,好奇上網搜了一下證書的價格,發現還是不便宜的,現在似乎是一門生意了。
完整性驗證
如何驗證內容的完整性?這裏用到了消息驗證碼 (Message Authentication Code),應用層發送數據時會附加一種叫做 MAC(Message Authentication Code)的報文摘要。 MAC能夠查知報文是否遭到篡改,從而保護報文的完整性。下面簡單介紹一下 MAC。
前提:雙方都持有對稱加密中的公有密鑰
-
發送方使用一些公開的 MAC 算法,輸入消息和公有密鑰,產生一個 MAC 值。
-
發送方將消息與 MAC 一起轉發。
-
在接收到消息和 MAC 後,接收方將接收到的消息和公有密鑰 K 送到 MAC 算法中,並重新計算 MAC 值。
-
接收方檢查新計算的 MAC 與從發送方接收到的 MAC 是否相等。如果它們匹配,則接收方接受消息。
-
如果計算出的 MAC 與發送方發送的 MAC 不匹配,則接收方無法確定是消息被篡改還是來源被篡改,不接受消息。
完整的 HTTPS 通信步驟
基本上 HTTPS 就依靠以上這些步驟來建立安全的通信,下面看一個實際的例子。這裏是複製的《圖解HTTP》 一書中的案例,向作者致敬!
- 客戶端通過發送 Client Hello 報文開始 SSL 通信。報文中包含客戶端支持的 SSL 的指定版 本、加密組件(Cipher Suite)列表(所使用的加密算法及密鑰長度等)。
- 服務器可進行 SSL 通信時,會以 Server Hello 報文作爲應答。和客戶端一樣,在報文中包含 SSL 版本以及加密組件。服務器的加密組件內容是從接收到的客戶端加密組件內篩選出來的。
- 之後服務器發送 Certificate 報文。報文中包含公開密鑰證書。
- 最後服務器發送 Server Hello Done 報文通知客戶端,最初階段的 SSL 握手協商部分結束。
- SSL 第一次握手結束之後,客戶端以 Client Key Exchange 報文作爲迴應。報文中包含通信加 密中使用的一種被稱爲 Pre-master secret 的隨機密碼串。該報文已用步驟 3 中的公開密鑰進行加密。
- 接着客戶端繼續發送 Change Cipher Spec 報文。該報文會提示服務器,在此報文之後的通信 會採用 Pre-master secret 密鑰加密。
- 客戶端發送 Finished 報文。該報文包含連接至今全部報文的整體校驗值。這次握手協商是否 能夠成功,要以服務器是否能夠正確解密該報文作爲判定標準。
- 服務器同樣發送 Change Cipher Spec 報文。
- 服務器同樣發送 Finished 報文。
- 服務器和客戶端的 Finished 報文交換完畢之後,SSL 連接就算建立完成。當然,通信會受到 SSL 的保護。從此處開始進行應用層協議的通信,即發送 HTTP 請求。
- 應用層協議通信,即發送 HTTP 響應。
- 最後由客戶端斷開連接。斷開連接時,發送 close_notify 報文。上圖做了一些省略,這步之 後再發送 TCP FIN 報文來關閉與 TCP 的通信。
總結
- HTTPS 比 HTTP 更加安全,主要是利用了 SSL/TLS,HTTP 先和它們通信,然後再經過TCP。
- SSL 利用非對稱加密來建立 SSL,後續通過對稱加密來傳遞信息。
- SSL 的非對稱加密的公鑰通過 CA 頒發的證書,利用 CA 的公鑰來驗證,一般內置在客戶端中。
- 報文的完整性,通過消息驗證碼(MAC)來驗證。