【TCP/IP】HTTP協議與HTTPS的加密流程

1、HTTP基礎知識

HTTP全稱Hyper Text Transfer Protocol,即超文本傳輸協議。HTTP是一個應用層協議,可視爲一個在計算機世界裏專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規範。面試

1. HTTP請求流程

咱們這裏就直接以一個常見的面試題引入啦。算法

在瀏覽器中輸入 www.baidu.com 後會發生什麼?數據庫

當一個用戶在瀏覽器裏輸入 www.baidu.com 這個 URL 時,將會發生不少操做。首先它會請求 DNS 把這個域名解析成對應的 IP 地址,而後根據這個 IP 地址在互聯網上找到對應的服務器,向這個服務器發起一個GET 請求,由這個服務器決定返回默認的數據資源給訪問用戶。在服務器端實際上還有很複雜的邏輯:服務器可能有好多臺,到底指定哪臺服務器來處理請求,這須要一個負載均衡設備來平均分配全部用戶的請求;還有請求的數據是存儲在分佈式緩存裏仍是一個靜態文件中,或是在數據庫裏;當數據返回瀏覽器時,瀏覽器解析數據發現還有一些靜態資源(如 CSS、JS 或者圖片)時又會發起另外的 HTTP 請求,而這些請求有可能會在 CDN 上,那麼 CDN 服務器又會處理這個用戶的請求,大致上一個用戶請求會涉及這麼多操做。每個細節都會影響這個請求最終是否會成功。後端

咱們不去涉及其中過多的知識,單說HTTP的請求流程便可,從上面咱們知道,HTTP協議是由客戶端發起的,由請求和響應構成,是一個標準的客戶端服務器模型(C/S),它的具體流程以下:瀏覽器

  1. 地址解析。域名系統DNS解析域名獲得主機的IP地址;緩存

  2. 封裝HTTP請求數據包。封裝的內容有以上部分結合本機本身的信息;安全

  3. 封裝成TCP包,創建TCP鏈接(TCP的三次握手);服務器

  4. 客戶機發送請求命令。 創建鏈接後,客戶機向服務器發送一個請求;markdown

  5. 服務器響應。服務器接到請求後,給予相應的響應信息;網絡

  6. 服務器關閉TCP鏈接。通常Web服務器向瀏覽器發送了請求數據,它要關閉TCP鏈接;

  7. 客戶端解析報文。客戶端接收到響應報文後解析HTML代碼,並渲染。

2. 常見狀態碼

HTTP常見的狀態碼分爲五大類,以下表所示:

狀態碼類別 具體含義 常見狀態碼
1xx 提示信息,表示目前是協議處理的中間狀態,還須要後續的操做
2xx 成功,報文已經收到並被正確處理 200、20四、206
3xx 重定向,資源位置發生變更,須要客戶端從新發送請求 30一、30二、304
4xx 客戶端錯誤,請求報文有誤,服務器沒法處理; 400、40三、404
5xx 服務器錯誤,服務器在處理請求時內部發生了錯誤。 500、50一、50二、503
  • 1xx:1xx類狀態碼屬於提示信息,是協議處理中的一種中間狀態,實際用到的比較少。

  • 2xx:2xx類狀態碼錶示成功處理了客戶端需求,也是咱們瀏覽器發起請求時常見的狀態:

    • 【200 OK】:最多見的成功狀態碼,表示一切正常。若是是非HEAD請求,服務器返回的響應頭都會有 body 數據;
    • 【204 No Content】:也是常見的成功狀態碼,與 200 OK 基本相同,但響應頭沒有 body 數據;
    • 【206 Partial Content】:是應用於 HTTP 分塊下載或斷點續傳,表示響應返回的 body 數據並非資源的所有,而是其中的一部分,也是服務器處理成功的狀態;
  • 3xx:3xx類狀態碼錶示客戶端請求的資源發生了變更,須要客戶端用新的 URL 從新發送請求獲取資源,也就是重定向

    • 【301 Moved Permanently】:表示永久重定向,說明請求的資源已經不存在了,需改用新的 URL 再次訪問;
    • 【302 Found】:表示臨時重定向,說明請求的資源還在,但暫時須要用另外一個 URL 來訪問;

    注:301 和 302 都會在響應頭裏使用Location,指明後續要跳轉的 URL,瀏覽器會自動重定向新的 URL。

  • 4xx:4xx類狀態碼錶示客戶端發送的報文有誤,服務器沒法處理,也就是錯誤碼的含義:

    • 【400 Bad Request】:表示客戶端請求的報文有錯誤,但只是個籠統的錯誤;
    • 【403 Forbidden】:表示服務器禁止訪問資源,並非客戶端的請求出錯;
    • 【404 Not Found】:表示請求的資源在服務器上不存在或未找到,因此沒法提供給客戶端。
  • 5xx:5xx類狀態碼錶示客戶端請求報文正確,可是服務器處理時內部發生了錯誤,屬於服務器端的錯誤碼:

    • 【500 Internal Server Error】:與400相似,是個籠統通用的錯誤碼,服務器發生了什麼錯誤,咱們並不知道;
    • 【501 Not Implement】:表示客戶端請求的功能還不支持,相似」即將開業,盡情期待「的意思;
    • 【502 Bad Gatwy】:一般是服務器做爲網關或代理時返回的錯誤碼,表示服務器自身工做正常,訪問後端服務器發生了錯誤;
    • 【503 Service Unavailable】:表示服務器當前很忙,暫時沒法響應服務器,相似」網絡服務正忙,請稍後重試「的意思。

3. 常見字段

首先咱們瞭解一下HTTP的報文結構,大概以下:

這是常見的請求報文,固然還有響應報文,二者之間並不徹底一致,這裏只簡單說起一下請求報文的格式。

首先是請求方法,常見的請求方法有 GET和POST兩種,以後跟着的是URL,即要訪問的地址,再後面跟着的就是協議版本,如:HTTP/1.1。

咱們主要講解以後跟着的字段,即請求頭,請求頭的字段常以key-value的形式,即」屬性名:屬性值「的形式傳遞若干數據,服務端據此獲取客戶端的信息。接下來咱們就來了解常見的字段:

  • Accept字段與Content-type字段:

Accept字段用於客戶端向服務器發送報文時表示本身可接收的響應內容類型,如:Accept:text/plain (文本類型);

相似的字段還有Accept-Charset 表示可接收的字符集;Accept-Encoding表示可接受的響應內容的壓縮方式 ;Accept-Language表示可接受的響應內容語言列表; Accept-Datetime表示可接受的按照時間來表示的響應內容版本。

Content-Type字段用於服務器迴應時,告訴客戶端,本次數據的格式是什麼。

相似的字段還有Content-Encoding字段表示數據的壓縮方法,表示服務器返回的數據使用什麼壓縮格式。

  • Host字段

    Host字段用於客戶端發送請求時,用來指定服務器的域名。例如:Host:www.baidu.com。這裏須要與報文中的請求行的 URL 區分,Host字段與 URL 組成完整的請求URL,例如請求行中的URL爲/getPerson,而Host字段爲www.baidu.com,那麼二者結合起來就是www.baidu.com/getPerson

  • Connection字段

    Connection字段最經常使用於客戶端要求服務器使用 TCP 持久鏈接,以便其餘請求複用。

    Connection: keep-alive

    擴展:

    • HTTP是無狀態的面向鏈接的協議,無狀態並不表明HTTP不能保持TCP鏈接,HTTP使用的不是UDP(無鏈接);

    • HTTP/1.1 版本的默認鏈接都是持久鏈接,但爲了兼容老版本的 HTTP,須要指定Connection首部字段的值爲Keep-Alive。簡單的說,當一個網頁打開完成後,客戶端和服務器之間用於傳輸的 HTTP 數據的 TCP 鏈接不會馬上關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接;

    • Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間。

  • Content-Length字段

    服務器在返回數據時,會有Content-Length字段,代表本次迴應的數據長度。例如:Content-Length: 1000,這代表了服務器本次迴應的數據長度是1000個字節,後面的字節就屬於下一個迴應了。

2、 HTTP存在的問題

1. 性能問題

在 HTTP/1.0 中有很大的性能問題,每次發起一個HTTP請求,都須要去創建一次TCP鏈接,並且仍是串行請求,這使得 HTTP 在 TCP 的鏈接創建上花費了大量的開銷。對於這種問題,HTTP/1.1 中提出了長鏈接的通訊方式,也叫持久鏈接。這種鏈接的好處在於減小了 TCP 鏈接的重複創建和斷開所形成的額外開銷,減輕了服務器端的負載:

HTTP/1.1 採用了長鏈接的方式,這使得管道(Pipeline)網絡傳輸成爲了可能。便可在同一個 TCP 鏈接裏面,客戶端能夠發起多個請求,只要第一個請求發出去了,沒必要等其回來,就能夠發第二個請求出去,能夠減小總體的響應時間。

可是服務器仍是按照順序,先回應第一個請求,完成後再回應第二個請求,以此類推。要是前面的請求迴應得特別慢,後面就會有許多請求阻塞着,這就是所謂的【隊頭阻塞】。

因此 HTTP/1.0 或是 HTTP/1.1 性能都不是很完美,因此後續會有其餘增強。

2. 安全問題

HTTP的內容是明文傳輸的,明文數據會通過中間代理服務器、路由器、WIFI熱點、通訊服務運行商等多個物理節點,若是信息在傳輸過程當中被劫持,傳輸的內容久徹底暴露了,劫持者還能夠篡改傳輸的信息且不被雙方察覺,這就是中間人攻擊

總結一下,HTTP在安全方面有如下三個問題:

  • 使用明文通訊,一些重要的內容會被竊聽;
  • 不能驗證對方身份,多是僞造的信息;
  • 沒法驗證報文的完整性,有可能被修改;

3、HTTPS的實現

針對上面咱們提到的HTTP的安全問題,HTTPS 在 HTTP 的基礎上增長了加密處理、認證機制和完整性保護,咱們能夠將 HTTPS = HTTP + 加密 + 認證 + 完整性保護

1. 加密

由於 HTTP 使用明文傳輸,中間會通過多個物理節點,可能會被劫持竊聽,針對這一問題,HTTPS 採用了加密的方式解決。最容易理解的就是對稱加密。

1.1 對稱加密

對稱加密好理解,就是咱們擁有一個密鑰,它能夠用來對一段內容進行加密,一樣的,在內容被進行加密後,須要用同一個密鑰對加密內容進行解密,才能看到本來的內容,能夠看做咱們平常生活中的鑰匙。

HTTP 能夠直接使用對稱加密嗎?

固然不能夠。若是通訊雙方各自持有同一個密鑰,且沒有第三方知曉,那麼這兩方之間的通訊安全是能夠被保證的(畢竟密鑰被破解可能性不大)。問題是」如何使得這個密鑰可讓傳輸的雙方知曉,同時不被別人知道「?

假如咱們如今瀏覽器生成一個密鑰而後發送到服務端,告訴服務端咱們雙方用這個密鑰來加密傳輸文件。或者是放過來,由服務器生成密鑰而後發送給瀏覽器。很明顯這就不現實,咱們知道 HTTP 傳輸時中間是須要通過許多箇中間節點的,在通過中間節點時這個密鑰被劫持下來是一件十分容易的事,因此這種方式不可取。由此引入非對稱加密

1.2 非對稱加密

非對稱加密有兩把密鑰,一般一把叫作公鑰,另一把叫作私鑰。用公鑰加密的內容必須用私鑰才能解開,一樣的,私鑰加密的內容須要用公鑰才能解開。

HTTP 能夠直接使用非對稱加密嗎?

仍是不能夠。鑑於非對稱加密的性質,咱們可能會有這種思路:服務器先把公鑰直接明文傳輸給瀏覽器,以後瀏覽器向服務器傳數據前都先用這個公鑰加密好再傳輸,這條數據彷佛能夠保障了,由於只有服務器端的相應私鑰能解開這條數據。可是這樣仍是有問題,密鑰仍是能夠被劫持的。

若是服務器用它的的私鑰加密數據傳給瀏覽器,那麼瀏覽器用公鑰能夠解密它,而這個公鑰是一開始經過明文傳輸給瀏覽器的,若是這個公鑰被誰劫持到的話,他也能用該公鑰解密服務器傳來的信息了。因此這種方式的實現仍是會有問題,彷佛只能保證由瀏覽器傳輸數據時的安全性(其實還有漏洞)。

1.3 改良版非對稱加密

經過一組公鑰、私鑰已經能保證單個方向傳輸的安全性,那用兩組公鑰私鑰是否是就能保證雙向傳輸都安全了,如下面流程爲例:

  1. 某網站擁有用於非對稱加密的公鑰 A、私鑰 A‘,瀏覽器擁有用於非對稱加密的公鑰 B、私鑰 B’ ;
  2. 瀏覽器向網站服務器發起請求,服務器把公鑰 A 明文傳輸給瀏覽器;
  3. 瀏覽器將公鑰 B 明文傳輸給服務器;
  4. 以後瀏覽器向服務器傳輸的全部東西都用公鑰 A 加密,服務器收到後用私鑰 A’ 解密。因爲只有服務器擁有這個私鑰 A’ 能夠解密,因此能保證這條數據的安全;
  5. 服務器向瀏覽器傳輸的全部東西都用公鑰 B 加密,瀏覽器收到後用私鑰 B’ 解密。同上也能夠保證這條數據的安全。

這種實現方式理論上確實可行,拋開這裏面仍有的漏洞不談(下文再述),HTTPS 的加密卻沒有使用這種方案,爲何?

最主要的緣由是非對稱加密算法很是耗時,特別是加密解密一些較大數據的時候有些力不從心。相比之下,對稱加密就要快不少,那能不能同時運用對稱加密與非對稱加密的性質來實現對 HTTP 的加密呢?

1.4 混合加密

既然非對稱加密耗時,那麼就用「對稱加密 + 非對稱加密」結合的形式來實現對 HTTP 的加密,並且還得儘可能減小非堆成加密的次數 ,這樣是否能實現呢?

這種方式是能夠實現的,並且非對稱加密、解密各只須要用一次便可。請看如下過程:

  1. 某網站擁有非對稱加密的公鑰 A、私鑰 A‘ ;
  2. 瀏覽器向網站服務器發起請求,服務器把公鑰 A 明文傳輸給瀏覽器;
  3. 瀏覽器隨機生成一個用以對稱加密的密鑰 X,用公鑰 A 加密後傳給服務器;
  4. 服務器端拿到加密的密鑰後,用公鑰 A 解密獲得密鑰 X;
  5. 這樣雙方就都擁有密鑰 X 了,且別人沒法知道它,以後雙方全部數據都用密鑰 X 進行加密解密。

HTTPS 基本上就是採用了這種方案了,固然這種方法仍是有漏洞,咱們接着往下講。

2. 認證

2.1 中間人攻擊

根據上面的混合加密過程,中間人確實沒法擁有瀏覽器生成的對稱密鑰 X,這個密鑰自己就被公鑰 A 給加密了,只有服務器才能經過私鑰 A‘ 對其進行解密。然而在這個過程當中中間人徹底不須要獲取到密鑰 A’ 就能進行攻擊了。以下流程所示:

  1. 某網站擁有用於非對稱加密的公鑰A、私鑰A’ ;
  2. 瀏覽器向網站服務器發起請求,服務器把公鑰 A 明文給傳輸瀏覽器;
  3. 中間人劫持到公鑰A,保存下來,把數據包中的公鑰A替換成本身僞造的公鑰B(它固然也擁有公鑰B對應的私鑰B’)
  4. 瀏覽器隨機生成一個用於對稱加密的密鑰X,用公鑰B(瀏覽器不知道公鑰被替換了)加密後傳給服務器;
  5. 中間人劫持後用私鑰 B’ 解密獲得密鑰 X,再用公鑰 A 將 X 加密後傳給服務器
  6. 服務器拿到後用私鑰A’解密獲得密鑰X。

這樣在雙方都不會發生異常的狀況下,中間人獲得了密鑰 X,這其中的根本緣由就是瀏覽器沒法確認本身收到的公鑰是否是網站的。那麼接下來就是要解決這一問題。

2.2 數字證書

如何證實瀏覽器收到的公鑰必定是該網站的公鑰?這裏就須要有一個公信機構給網站頒發一個「身份證」了。網站在使用 HTTPS 前,須要向「CA機構」申請頒發一份數字證書,數字證書裏有證書持有者、證書持有者的公鑰等信息,服務器把證書傳輸給瀏覽器,瀏覽器從證書裏取公鑰就好了,證書就如同身份證同樣,能夠證實「該公鑰對應該網站」。

然而到這裏仍是有一個問題,如何保證證書在傳輸的過程不會被篡改,身份證自己有防僞的技術,那麼如何保證證書的防僞呢?

2.3 數字簽名

如何保證證書不被篡改?

咱們把證書內容生成一份「簽名」,比對證書內容和簽名是否一致就能察覺是否被修改,這種技術就稱爲數字簽名

數字簽名的製做過程?

  1. CA 擁有非對稱加密的私鑰和公鑰;
  2. CA 對證書明文信息進行 Hash;
  3. 對 Hash 後的值用私鑰加密,獲得數字簽名S;

將明文和數字簽名共同組成數字證書,這樣一份證書就能夠頒發給網站了。

瀏覽器獲得證書後如何驗證這份證書的真實性?

  1. 拿到服務器發送過來的證書,獲得明文T,數字簽名S;
  2. 用CA機構的公鑰對 S 解密(因爲是瀏覽器信任的機構,因此瀏覽器保有CA的公鑰),獲得S‘;
  3. 瀏覽器用證書說明的 Hash 算法對明文 T 進行 Hash 獲得 T’;
  4. 比較 S‘ 是否等於 T’,等於則表明證書可信。

瀏覽器如何獲得權威機構的公鑰?

上面提到,如何要對服務器發過來的證書進行解密,那麼就須要到CA的公鑰,由於其被CA的私鑰給加密了。那麼瀏覽器是如何擁有CA的公鑰呢?

實際上權威機構的公鑰並不須要傳輸,由於權威機構會和主流的瀏覽器或操做系統合做,將他們的公鑰內置在瀏覽器或操做系統環境中。客戶端收到證書以後,只須要從證書中找到權威機構的信息,並從本地環境中找到權威機構的公鑰,就能正確解密A公鑰。固然實際狀況要比這個複雜得多,這裏簡單介紹就行。

中間人有可能篡改證書嗎?

上面咱們提到,權威機構的公鑰是可能在瀏覽器或操做系統中的,那麼中間人劫持到證書後是能夠解密獲得原文的。相應的,他也能夠去篡改證書的原文,可是因爲他沒有 CA 機構的私鑰,沒法相應地篡改簽名。因此瀏覽器收到證書後會發現原文和解密後的值不一致,說明證書已經被篡改,證書不可信了,因此中間人不可能去篡改證書了。

4、HTTPS的請求流程

  1. 客戶端向服務器發起 HTTPS 請求,鏈接到服務器的 443 端口;
  2. 服務器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,服務器端保存着私鑰,不能將其泄露,公鑰能夠發送給任何人;
  3. 服務器將本身的公鑰包含在權威機構發佈的證書中發送給客戶端;
  4. 客戶端收到服務器端的證書以後,會對證書進行檢查,驗證其合法性,若是發現發現證書有問題,那麼HTTPS傳輸就沒法繼續。嚴格的說,這裏應該是驗證服務器發送的數字證書的合法性,關於客戶端如何驗證數字證書的合法性。若是公鑰合格,那麼客戶端會生成一個隨機值,這個隨機值就是用於進行對稱加密的密鑰,咱們將該密鑰稱之爲client key,即客戶端密鑰,這樣在概念上和服務器端的密鑰容易進行區分。而後用服務器的公鑰對客戶端密鑰進行非對稱加密,這樣客戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束;
  5. 客戶端會發起 HTTPS 中的第二個 HTTP 請求,將被公鑰所加密以後的客戶端密鑰發送給服務器;
  6. 服務器接收到客戶端發來的密文以後,會用本身的私鑰對其進行非對稱解密,解密以後的明文就是客戶端密鑰,而後用客戶端密鑰對數據進行對稱加密,這樣數據就變成了密文。
  7. 而後服務器用對稱加密的密鑰(即客戶端密鑰)對報文進行加密,並將加密後的報文發送給客戶端;
  8. 客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,獲得服務器發送的數據。這樣 HTTPS 中的第二個 HTTP 請求結束,整個 HTTPS 傳輸完成。

文章內容絕大數來源網絡,我只是個搬運工,如有哪裏出錯,請評論區指出。

參考資料:

相關文章
相關標籤/搜索