前言
因為工作需要,需要用到大量的關於 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)來驗證。