一、HTTP Begin
1、什么是 HTTP
HTTP 是基于文本傳輸的協議,它位于 OSI 七層模型的應用層(Application) ,HTTP 是通過客戶端向服務器發送請求,服務器響應請求來進行通訊,截止到目前位置 HTTP 協議分別由 6 個獨立的協議說明組成,這 6 個協議說明分別是 RFC 7230 、 RFC 7231 、 RFC 7232 、 RFC 7233 、 RFC 7234 、 RFC 7235 。
說到 HTTP 就不得不說通訊報文,下面我們來看看 HTTP 通訊報文。通訊報文分為 請求報文 和 響應報文 。
①請求報文
HTTP請求報文通常由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組,如下圖所示:
請求行包含請求方法、URL 和 HTTP 協議版本三個字段組成,在這里需要說的是 請求方法可以實 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT,但是常見的經常用到的就是 GET、POST、DELETE和 PUT。
請求頭部由大量鍵值對組成,請求頭部的數據都是向服務器告知客戶端的信息,比較常見的請求頭有 User-Agent 瀏覽器類型,Accept 客戶端可識別的內容類型列表,Host 請求的主機名。接下來是一個空行,它主要用來通知服務器從當前行開始往下就不再是請求頭了。
請求數據主要是在 POST 和 PUT 方法中使用,用來向服務器提交客戶端的表單信息,一般需要配合著 Content-Type和Content-Length 使用。
②響應報文
響應報文也是由三部分組成,狀態行、消息報頭和響應正文。狀態行用來告知客戶端所請求資源的情況,狀態行由 HTTP 版本、服務器回發響應狀態碼和狀態碼文本描述組成。這里要說一下響應狀態碼,狀態碼類型如下表所示:
上表看著響應狀態碼很多,但是大部分在實際運用中很少遇到,經常遇到的狀態碼一共 7 中,如下表所示:
2、HTTP 致命缺點
HTTP 有一個致命的缺點,就是 HTTP 的報文都是以明文的方式進行傳輸,這樣就會導致中間人攻擊問題。什么是中間人攻擊了,下面我們通過圖文的形式講一下。
A 在客戶端向服務器發送了一句話“我今天很好”,這時在數據還沒有到達服務器的時候被 B 攔截到,B 將發送的內容改為“我昨天很好”并發送給服務器,最后服務器接收到的信息就是“我昨天很好”而不是“我今天很好”。
在這里 B 就是中間人,B 所執行的所有操作就叫做中間人攻擊,一圖勝千言我們來看圖。
3、HTTP 預防致命缺點手段
要想預防中間人攻擊我們就需要對發送的報文信息進行加密處理,一般來說我們會采用兩種加密手段來預防中間人攻擊:對稱加密和非對稱加密。
①對稱加密
首先 A 發送一條信息告訴服務器我要和你通訊了,服務器收到這條信息后響應一條信息告訴 A 的加密方式(例如 AES 加密)和密鑰,最后 A 用和服務器協商好的加密方式對信息進行加密并發送,服務器收到信息后利用密鑰進行解密即可。
通過上圖看出點什么沒?發送的內容雖然已經加密了,但是加密方式和密鑰依然是明文,中間人如果攔截到第一次通信的話,它就可以拿著攔截到的加密方式和密鑰就可以對后面的通信進行解密,修改內容后再以同樣的加密方式和密鑰進行加密后發送個服務器。
②非對稱加密
針對前面所說的情況我們可以使用非對稱加密對密鑰進行加密處理。同樣首先 A 發送一條信息告訴服務器我要和你通訊了,服務器收到這條信息后先利用非對稱加密(例如RSA)生成一個公鑰和一個私鑰,然后服務器將公鑰發發送給 A ,A 在本地生成一個密鑰并利用服務器發回的公鑰進行加密,完成后發送給服務器,服務器收到后利用私鑰進行解密得到對稱加密的密鑰,最后雙方利用約定好的加密方式和密鑰進行通信。
到目前為止看起來不錯密鑰和信息都加密了,應該就沒問題了吧。真的是這樣嗎,如果真的是這樣的話 HTTPS 就沒有出現的必要了。
既然密鑰都加密了,那么中間人在攔截到第一次通信時可以拿到服務器發給客戶端的加密方式和公鑰,然后自己生成一個私鑰和一個公鑰,并將攔截到的服務器發來的公鑰替換成自己生成的公鑰后發送給客戶端,這時客戶端加密 AES 密鑰的公鑰就是中間人的了。
客戶端對 AES 密鑰加密后發送給服務器,中間人再次攔截并利用自己的私鑰解析密文得到AES 密鑰,然后使用服務器的公鑰對 AES 密鑰加密并發送給服務器。最后在客戶端和服務器的整個通訊期間中間人就可以用接獲到 AES 密鑰對信息解密并修改。
到這里一定會由同學問,這兩種方法都無法完全避免中間人攻擊,還有其他的辦法嗎?下面我們偉大的 HTTPS 就要登場了,它可以完全避免中間人攻擊。
二、HTTPS End
1.什么是 HTTPS
HTTPS 就是 HTTP 和 TLS 的簡稱,以前的 HTTPS 使用的是 SSL ,現在的 HTTPS 使用的是 SSL 。TLS 整體上來說和非對稱加密是一樣的,主要是對 AES 密鑰加密的。
簡單來說就是 A 發送一條信息給服務器告訴服務器我要和你通信,然后服務器返回 TLS/SSL 證數,客戶端在收到證書后校驗證書的有效性,如果證書有效就生成生成 AES 密鑰并用證書中的公鑰加密,然后發送給服務器。服務器確認收到后,就可以利用 AES 密鑰進行加密通信了。
2.關于 CA 認證體系
CA 認證體系是 HTTPS 防止中間人攻擊的核心,客戶端需要對服務器發來的證書進行安全性校驗。那么客戶端是怎么校驗證書的安全性呢?下面我們來講解一下。
證書都是由權威的認證機構頒發的,并且這些認證機構辦法的證書目前已經內置到了操作系統中(windows 是這樣,其他的操作系統不慎了解),這些證書被稱為 CA 根證書。
當我們的服務器需要使用 HTTPS 的時候,就需要將服務器生成的公鑰和網站相關信息發給權威認證機構,然后權威認證機構通過服務器發送的相關信息用進行加簽,由此得到了服務器證書,這個證書對應的生成證書內容的簽名,并將該這個簽名使用權威認證機構的私鑰進行加密得到證書指紋,并且和上級證書生成關系鏈(上級證書最后都是 CA 根證書)。
當客戶端收到服務器發來的證書后,首先會通過層級關系找到上級證書,然后利用上級證書里的公鑰解密服務器證書的證書指紋,解密后得到簽名。
然后通過簽名算法算出服務器證書的簽名,并對比兩個簽名是否一樣,一樣就說明服務器發來的證書是不存在問題的。
這里證書校驗用的 RSA 是通過私鑰加密證書簽名,公鑰解密來巧妙的驗證證書有效性的。通過 CA 認證體系就可以避免了中間人竊取 AES 密鑰并發起攔截和修改 HTTP 通訊的報文。
三、總結
這篇文章嘮嘮叨叨的講了這么多關于 HTTP 和 HTTPS 的知識,看似很基礎其實在很多時候我們發出去或接受到的數據不準確其實就是因為中間人攻擊造成的,因此我們在開發部署網站的時候應該盡可能的使用 HTTPS 。
- 作者:朱鋼,筆名喵叔
- 簡介:.NET 高級開發人員,2019 年度博客之星 20 強,長期從事電子政務系統和AI客服系統的設計與開發,目前就職于國內某 BIM 大廠從事招投標軟件的開發。
- 編輯:陶家龍
- 征稿:有投稿、尋求報道意向技術人請私信小編