全面理解HTTP&HTTPS協議

該文章是我本身學習筆記及理解,但願通篇讀完能讓你對HTTP和HTTPS有一個更全面的理解,若是錯誤地方煩請指正。文字較多,全篇預計閱讀耗時20分鐘。html

HTTP

介紹

超文本傳輸協議(英語:HyperText Transfer Protocol,縮寫:HTTP)是一種用於分佈式、協做式和超媒體信息系統的應用層協議[1]。HTTP是萬維網的數據通訊的基礎。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。經過HTTP或者HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,URI)來標識。《維基百科》前端

從 1990 年開始HTTP就在 WWW 上普遍應用。HTTP協議採用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含請求的方法、URI、協議版本、以及包含請求修飾符、客戶 信息和內容的相似於MIME的消息結構。服務器以一個狀態行做爲響應,相應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容。程序員

  • HTTP是基於TCP/IP通訊協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)
  • HTTP協議一般承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了咱們常說的HTTPS。
  • HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。
  • HTTP默認的端口號爲80,HTTPS的端口號爲443

發展

HTTP剛出現是爲了將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器,隨着WEB的持續發展,例如CSS、JS豐富了頁面展現和基於HTTP協議的ajax增長了咱們向服務器獲取數據的方式,HTTP也不斷的進行優化迭代。web

版本 發佈時間 主要內容 現狀
HTTP/0.9 1991 無狀態、只支持GET請求、無協議頭、只支持純文本 已過期
HTTP/1.0 1996 有協議頭、支持GET/POST/HEAD等方法、傳輸內容不限 仍被採用
HTTP/1.1 1999 默認持久鏈接、請求管道化、增長緩存處理、增長Host字段、支持斷點傳輸、增長錯誤通知處理 目前最被普遍使用
HTTP/2 2015 新的二進制格式(幀)、多路複用、header壓縮、請求優先級、服務端推送 將來的發展趨勢
HTTP/3 2018.11 新的二進制格式(幀)、多路複用、header壓縮、請求優先級、服務端推送 發展中

HTTP/2

HTTP/2繼承於Google的SPDY協議。HTTP/2: the Future of the Internet | Akamai這是Akamai公司用來講明HTTP/2的優點所建立的demo。同時請求379張圖片,HTTP/2速度佔了絕對的優點。
ajax

1. 二進制分幀

HTTP 2.0 的全部幀都採用二進制編碼算法

  • 幀:客戶端與服務器經過交換幀來通訊,幀是基於這個新協議通訊的最小單位。
  • 消息:是指邏輯上的 HTTP 消息,好比請求、響應等,由一或多個幀組成。
  • 流:流是鏈接中的一個虛擬信道,能夠承載雙向的消息;每一個流都有一個惟一的整數標識符(一、2 … N);

2. 多路複用

之因此速度能有如此優化,主要得益於HTTP2.0的多路複用技術。
有了新的分幀機制後,HTTP/2再也不依賴多個TCP 鏈接去處理更多併發的請求,每一個數據流都拆分紅不少互不依賴的幀,而這些幀能夠交錯(亂序發送),還能夠分優先級。最後再在另外一端根據每一個幀首部的流標識符把它們從新組合起來。從始至終,客戶端與服務器之間只須要一個鏈接(同個域名下)便可。 segmentfault

3. 頭部壓縮

HTTP 協議不帶有狀態,每次請求都必須附上全部信息。因此,請求的不少字段都是重複的,好比Cookie和User Agent,如出一轍的內容,每次請求都必須附帶,這會浪費不少帶寬,也影響速度。
HTTP/2 對這一點作了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮後再發送;另外一方面,客戶端和服務器同時維護一張頭信息表,全部字段都會存入這個表,生成一個索引號,之後就不發送一樣字段了,只發送索引號,這樣就提升速度了。瀏覽器

4. 數據流

由於 HTTP/2 的數據包是不按順序發送的,同一個鏈接裏面連續的數據包,可能屬於不一樣的迴應。所以,必需要對數據包作標記,指出它屬於哪一個迴應。
HTTP/2 將每一個請求或迴應的全部數據包,稱爲一個數據流(stream)。每一個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬於哪一個數據流。另外還規定,客戶端發出的數據流,ID一概爲奇數,服務器發出的,ID爲偶數。
數據流發送到一半的時候,客戶端和服務器均可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的惟一方法,就是關閉TCP鏈接。這就是說,HTTP/2 能夠取消某一次請求,同時保證TCP鏈接還打開着,能夠被其餘請求使用。
客戶端還能夠指定數據流的優先級。優先級越高,服務器就會越早迴應。緩存

5. 服務器推送

HTTP/2 容許服務器未經請求,主動向客戶端發送資源,這叫作服務器推送(server push)。常見場景是客戶端請求一個網頁,這個網頁裏面包含不少靜態資源。服務端能在客戶端請求靜態資源前主動把這些靜態資源隨着網頁一塊兒發給客戶端了,省去了客戶端創建鏈接、發起請求等過程,極大提高了速度。安全

存在的問題

因爲底層支持TCP協議的缺陷,致使HTTP/2仍是存在一些問題。

  • TCP+TLS創建鏈接耗時 HTTP/2使用TCP協議來傳輸的,而若是使用HTTPS的話,還須要使用TLS協議進行安全傳輸,而使用TLS也須要一個握手過程。整個啓動過程須要耗時3~4個RTT(往返時延)。
  • 隊頭阻塞 雖然HTTP/2的傳輸連接能夠多路複用,但TCP爲了保證傳輸可靠有序,有個特別的「丟包重傳」機制,丟失的包必需要等待從新傳輸確認,HTTP/2出現丟包時,整個 TCP 都要開始等待重傳。例如單個TCP連接同時承載了三路連接,當其中某一路出現丟包,則其餘兩路都會受到影響,必須從丟包時刻開始重傳。若是丟包率太高時,HTTP/2傳輸不如HTTP/1.1。

HTTP/3

因爲TCP從1970年發明至今已經存在了太多年,存在於各類設備中,去修改TCP協議是不可能完成的事。HTTP/3 拋棄 TCP 協議,以全新的視角從新設計 HTTP。其底層支撐是 QUIC 協議,該協議基於 UDP,有 UDP 特有的優點,同時它又取了 TCP 中的精華,實現了即快又可靠的協議

  • 實現了相似TCP的流量控制、傳輸可靠性的功能。 雖然UDP不提供可靠性的傳輸,但QUIC在UDP的基礎之上增長了一層來保證數據可靠性傳輸。它提供了數據包重傳、擁塞控制以及其餘一些TCP中存在的特性。
  • 實現了快速握手功能。 因爲QUIC是基於UDP的,因此QUIC能夠實現使用0-RTT或者1-RTT來創建鏈接,這意味着QUIC能夠用最快的速度來發送和接收數據,這樣能夠大大提高首次打開頁面的速度。0RTT 建連能夠說是 QUIC 相比 HTTP2 最大的性能優點。
  • 集成了TLS加密功能。 目前QUIC使用的是TLS1.3,相較於早期版本TLS1.3有更多的優勢,其中最重要的一點是減小了握手所花費的RTT個數。
  • 多路複用,完全解決TCP中隊頭阻塞的問題 和TCP不一樣,QUIC實現了在同一物理鏈接上能夠有多個獨立的邏輯數據流(以下圖)。實現了數據流的單獨傳輸,就解決了TCP中隊頭阻塞的問題。

HTTP/3相比於HTTP/2改動很大,因此目前還存在一些問題,例如與舊設備的兼容、服務器的推送濫用、缺乏配套調試工具等,相信隨着時間流逝,HTTP/3會愈來愈完善。

HTTP請求過程

  1. 域名解析。如用瀏覽器訪問http://hackr.jp/xss/web頁面,須要域名系統DNS解析域名hackr.jp,得主機的IP地址 20X.189.105.112,接着結合本機信息封裝成HTTP請求數據包。
  2. 創建鏈接(TCP三次握手)。在HTTP工做開始以前,客戶端首先要經過網絡與服務器創建鏈接,該鏈接是經過TCP來完成的,通常TCP鏈接的端口號是80。
  3. 客戶端發送請求。創建鏈接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可內容。
  4. 服務器響應。服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
  5. 服務器關閉鏈接。 通常狀況下,一旦Web服務器向瀏覽器發送了請求數據,它就要關閉TCP鏈接,而後若是瀏覽器或者服務器在其頭信息加入了這行代碼: Connection:keep-alive,TCP鏈接在發送後將仍然保持打開狀態,因而,瀏覽器能夠繼續經過相同的鏈接發送請求。保持鏈接節省了爲每一個請求創建新鏈接所需的時間,還節約了網絡帶寬。

Request

一個完整的請求由請求行請求頭請求體三部分組成。

請求行

請求行包含:請求方法、請求地址(URL)和協議版本。

請求方法
方法名 功能
GET 向指定的資源發出「顯示」請求,使用 GET 方法應該只用在讀取數據上,而不該該用於產生「反作用」的操做中
POST 指定資源提交數據,請求服務器進行處理(例如提交表單或者上傳文件)。數據被包含在請求文本中。這個請求可能會建立新的資源或者修改現有資源,或二者皆有。
PUT 向指定資源位置上傳其最新內容
DELETE 請求服務器刪除 Request-URI 所標識的資源
OPTIONS 使服務器傳回該資源所支持的全部HTTP請求方法。用*來代替資源名稱,向 Web 服務器發送 OPTIONS 請求,能夠測試服務器功能是否正常運做
HEAD 與 GET 方法同樣,都是向服務器發出指定資源的請求,只不過服務器將不傳回資源的本文部分,它的好處在於,使用這個方法能夠在沒必要傳輸所有內容的狀況下,就能夠獲取其中關於該資源的信息(原信息或稱元數據)
TRACE 顯示服務器收到的請求,主要用於測試或診斷
CONNECT HTTP/1.1 中預留給可以將鏈接改成通道方式的代理服務器。一般用於 SSL 加密服務器的連接(經由非加密的 HTTP 代理服務器)

請求頭

請求頭包含客戶端主機名和客戶端環境信息。 常見的請求頭

名稱 做用
Authorization 用於設置身份認證信息
User-Agent 用戶標識,如:OS 和瀏覽器的類型和版本
Accept-Encoding 告訴服務器能接受什麼編碼格式,如 gzip、deflate
If-Modified-Since 值爲上一次服務器返回的Last-Modified值,用於肯定某個資源是否被更改過,沒有更改過就從緩存中讀取
If-None-Match 值爲上一次服務器返回的 ETag 值,通常會和If-Modified-Since
Cookie 已有的Cookie
Referer 標識請求引用自哪一個地址,好比你從頁面 A 跳轉到頁面 B 時,值爲頁面 A 的地址
Host 請求的主機和端口號

通用的首部字段

名稱 做用
Cache-Control 響應輸出到客戶端後,服務端經過該屬性告訴客戶端該怎麼控制響應內容的緩存
Date 代表HTTP報文建立的日期和時間
Trailer 報文某段的的首部一覽
Warning 錯誤通知

請求體

請求體(又叫請求正文)是 post 請求方式中的請求參數,以 key = value 形式進行存儲,多個請求參數之間用&鏈接,若是請求當中請求體,那麼在請求頭當中的 Content-Length 屬性記錄的就是該請求體的長度

Response

一個完整的響應由響應行響應頭響應體三部分組成。

響應行

響應行包含:協議版本、狀態碼和狀態描述。

響應狀態碼

  • 2XX成功

    • 200(OK) 客戶端發過來的數據被正常處理
    • 204(Not Content) 正常響應,沒有實體
    • 206(Partial Content) 範圍請求,返回部分數據,響應報文中由Content-Range指定實體內容
  • 3XX重定向

    • 301(Moved Permanently) 永久重定向
    • 302(Found) 臨時重定向,規範要求,方法名不變,可是都會改變
    • 303(See Other) 和302相似,但必須用GET方法
    • 304(Not Modified) 狀態未改變, 配合(If-Match、If-Modified-Since、If-None_Match、If-Range、If-Unmodified-Since)
    • 307(Temporary Redirect) 臨時重定向,不應改變請求方法
  • 4XX客戶端錯誤

    • 400(Bad Request) 請求報文語法錯誤
    • 401 (unauthorized) 須要認證
    • 403(Forbidden) 服務器拒絕訪問對應的資源
    • 404(Not Found) 服務器上沒法找到資源
  • 5XX服務器錯誤

    • 500(internal sever error)表示服務器端在執行請求時發生了錯誤
    • 503(service unavailable)代表服務器暫時處於超負載或正在停機維護,沒法處理請求

響應頭

同請求頭同樣,用來傳遞附加信息。 常見的響應頭

名稱 做用
Accept-Ranges 是否接受字節範圍請求
ETag 表示你請求資源的版本,若是該資源發生啦變化,那麼這個屬性也會跟着變
Location 在重定向中或者建立新資源時使用
Set-Cookie 服務端能夠設置客戶端的cookie

響應體

響應體也就是網頁的正文內容,通常在響應頭中會用 Content-Length 來明確響應體的長度,便於瀏覽器接收,對於大數據量的正文信息,也會使用 chunked 的編碼方式。

HTTPS

介紹

回到開篇的圖片可知,HTTPS是在HTTP的基礎上加入了SSL/TLS協議,SSL/TLS依靠證書來驗證服務器的身份,並保護交換數據的隱私與完整性。爲了解決HTTP的明文通訊,沒法驗證對方身份和報文的完整性等問題,網景公司(Netscape)在1994年提出了HTTPS協議,隨後拓展到互聯網上。目前HTTPS已經取代HTTP成爲主流協議,並且HTTP/2以後都只能用於HTTPS加密鏈接。

安全通訊的實現

HTTPS 協議的主要功能基本都依賴於 TLS/SSL 協議,TLS/SSL 的功能實現主要依賴於三類基本算法:散列函數 、對稱加密和非對稱加密,其利用非對稱加密實現身份認證和密鑰協商,對稱加密算法採用協商的密鑰對數據加密,基於散列函數驗證信息的完整性。

1.保證通訊內容不被竊聽

  • 對稱加密 對稱密鑰(Symmetric-key algorithm)又稱爲共享密鑰加密,加密和解密使用相同的密鑰。常見的對稱加密算法有DES、3DES、AES、RC五、RC6。對稱密鑰的優勢是計算速度快,可是它有缺點,雙方須要都知道密鑰才能加解密,所以如何安全的發送密鑰給接收者成爲了一個問題。

  • 非對稱加密 公開密鑰加密(public-key cryptography)簡稱公鑰加密。公鑰能夠隨意分發,發送方使用公鑰進行加密處理,接收方用本身的私有私鑰進行解密。這種方式沒必要擔憂密鑰被攻擊者竊聽而盜走,但服務器沒法驗證公鑰信息,存在被中間人截獲替換的風險,另外非對稱加密的傳輸效率比對稱加密低。

  • 解決方案:對稱加密+非對稱加密 對稱加密效率高,非對稱加密能夠防止傳輸內容被截獲。結合二者的優點,HTTPS在交換祕鑰階段採用非對稱加密,創建通訊後經過對稱加密來傳遞信息。例如發送信息的一方先使用對方的公鑰加密對稱密鑰,對方接收到信息後用私鑰進行解密得到對稱密鑰,以後雙方的通訊都用對稱密鑰進行加解密。

2.保證報文不被篡改

  • 解決方案:數字簽名 因爲存在中間節點,傳遞的信息沒法被解密,但仍然可能被隨意篡改。爲了保證雙方發出和接受的是信息一致,可採用數字簽名的方式。 發送者先將公鑰、我的信息和其餘信息用Hash算法生成消息摘要,再用私鑰加密生成數字簽名。接收方收到公鑰、我的信息、其餘信息和數字簽名,從新用Hash算法生成消息摘要,並用公鑰解密數字簽名獲得的摘要進行校驗是否相同。 到此爲止,還存在一個最關鍵的問題:如何在互聯網上將公鑰安全的傳遞給對方?

3.驗證對方身份

  • 解決方案:數字證書 爲了防止中間人攻擊,掉包公鑰,咱們須要一個第三方權威機構來管理,讓第三方機構用其私鑰加密生成數字簽名,當接受到身份信息和公鑰後再用第三方機構的公鑰進行解密來比對信息摘要,這個第三方機構就是CA(Certification Authority)。向CA提交公鑰、組織信息、我的信息等信息並申請認證,認證經過後CA會向申請者頒發CA證書,證書內包含:申請者公鑰、申請者的組織信息和我的信息、簽發機構、CA的信息、有效時間、證書序列號等信息的明文,同時包含一個數字簽名。 CA自身的數字證書在咱們操做系統剛安裝好的時候,這些CA自身的數字證書就已經被微軟(或者其它操做系統)安裝在操做系統中了。而CA的公鑰就包含在其中。這樣,CA就能夠經過自身的私鑰對發佈的數字證書進行簽名,而在客戶端就可以用對應的公鑰來對其進行解密,確保了雙方能安全傳輸服務器公鑰。

完整過程

  1. 客戶端本地會存放着CA證書機構的公鑰,在發起HTTPS請求時,會首先向服務器第索要CA證書,並告發送隨機數A、支持的對稱加密算法、Hash算法等。
  2. 服務器收到信息後會將證書、加密算法、Hash算法、隨機數B等發給客戶端。
  3. 客戶端驗證證書是否有效,並使用CA證書機構的公鑰解密證書中的數字簽名,進行信息比對校驗。而後經過驗證事後的公鑰加密會話祕鑰(pre-master key)發送給服務器,這是惟一使用非對稱加密的地方。
  4. 服務器會使用私鑰解密獲得會話密鑰,並經過以前獲得的隨機數A、隨機數B和雙方肯定的加密算法生成一個最終的會話密鑰(master secret),服務器加密一段信息發給客戶端進行加密驗證。
  5. 客戶端也經過以前隨機數A、隨機數B和會話密鑰生成最終的會話密鑰,並對服務器的信息進行解密,若解密成功,雙方便結束驗證,用會話密鑰進行通訊。

至此,完成了服務器向客戶端的單向驗證,若要使客戶端對服務器也進行驗證操做(雙向驗證),則須要將CA證書放在客戶端。 若採用雙向驗證,則在步驟2服務器會額外向客戶端請求客戶端的CA證書信息,客戶端在步驟3驗證服務器證書後,會將客戶端證書發給服務器進行驗證。 雙向驗證能更好的預防中間人攻擊,客戶端內置了僅接受指定域名的證書,保障了客戶端與服務端通訊的惟一性和安全性,但要注意證書續期後需從新將證書放入到客戶端中。

用信鴿來解釋HTTPS

文章 用信鴿來解釋 HTTPS 詳細描述了整個過程,這裏再也不累述,想了解的能夠自行閱讀。

優勢&缺點

  • 優勢(安全性) 儘管HTTPS並不是絕對安全,掌握根證書的機構、掌握加密算法的組織一樣能夠進行中間人形式的攻擊,但HTTPS還是現行架構下最安全的解決方案,大幅增長了中間人攻擊的成本。
  • 缺點(成本&資源佔用) SSL證書需向CA機構購買,功能越強大費用越高;握手過程至少要增長1~2個RTT,且與純文本通訊相比,加密通訊會消耗更多的CPU及內存資源。(能夠經過性能優化提高性能)

HTTPS性能優化

  • CDN接入 HTTPS 增長的延時主要是傳輸延時 RTT,RTT 的特色是節點越近延時越小,CDN 自然離用戶最近,所以選擇使用 CDN 做爲 HTTPS 接入的入口,將可以極大減小接入延時。CDN 節點經過和業務服務器維持長鏈接、會話複用和鏈路質量優化等可控方法,極大減小 HTTPS 帶來的延時。
  • 會話緩存 雖然前文提到 HTTPS 即便採用會話緩存也要至少1*RTT的延時,可是至少延時已經減小爲原來的一半,明顯的延時優化;同時,基於會話緩存創建的 HTTPS 鏈接不須要服務器使用RSA私鑰解密獲取 Pre-master 信息,能夠省去CPU 的消耗。若是業務訪問鏈接集中,緩存命中率高,則HTTPS的接入能力講明顯提高。當前TRP平臺的緩存命中率高峯時期大於30%,10k/s的接入資源實際能夠承載13k/的接入,收效很是可觀。
  • 硬件加速 爲接入服務器安裝專用的SSL硬件加速卡,做用相似 GPU,釋放 CPU,可以具備更高的 HTTPS 接入能力且不影響業務程序的。測試某硬件加速卡單卡能夠提供35k的解密能力,至關於175核 CPU,至少至關於7臺24核的服務器,考慮到接入服務器其它程序的開銷,一張硬件卡能夠實現接近10臺服務器的接入能力。
  • 遠程解密 本地接入消耗過多的 CPU 資源,浪費了網卡和硬盤等資源,考慮將最消耗 CPU 資源的RSA解密計算任務轉移到其它服務器,如此則能夠充分發揮服務器的接入能力,充分利用帶寬與網卡資源。遠程解密服務器能夠選擇 CPU 負載較低的機器充當,實現機器資源複用,也能夠是專門優化的高計算性能的服務器。當前也是 CDN 用於大規模HTTPS接入的解決方案之一。
  • SPDY/HTTP2 前面的方法分別從減小傳輸延時和單機負載的方法提升 HTTPS 接入性能,可是方法都基於不改變 HTTP 協議的基礎上提出的優化方法,SPDY/HTTP2 利用 TLS/SSL 帶來的優點,經過修改協議的方法來提高 HTTPS 的性能,提升下載速度等。

Charles抓包HTTPS原理

Charles的抓包原理是假裝成中間人,攔截服務器響應,用Charles製做的CA證書替換服務器證書發給客戶端,再攔截客戶端響應用以前攔截的服務器證書公鑰從新加密發給服務器,讓雙方誤覺得仍是在正常的驗證通訊中。這一切發生的前提是客戶端選擇信任並安裝Charles的CA證書,不然客戶端校驗不過CA證書就會報錯並停止校驗。 具體過程如圖:

參考連接

HTTP 協議入門
HTTP 0.9 HTTP 1.0 HTTP 1.1 HTTP 2.0區別
HTTP 基礎與變遷
5分鐘讓你明白HTTP協議
程序員都該懂點 HTTP
前端必備HTTP技能之HTTP請求頭響應頭中經常使用字段詳解
解密HTTP/2與HTTP/3 的新特性
深刻理解HTTPS工做原理
也許,這樣理解HTTPS更容易
HTTP與HTTPS的區別
HTTPS協議詳解(五):HTTPS性能與優化
扯一扯HTTPS單向認證、雙向認證、抓包原理、反抓包策略

相關文章
相關標籤/搜索