[深入17] HTTP 和 HTTPS

woow_wu7發表於2020-03-09

導航

[深入01] 執行上下文
[深入02] 原型鏈
[深入03] 繼承
[深入04] 事件迴圈
[深入05] 柯里化 偏函式 函式記憶
[深入06] 隱式轉換 和 運算子
[深入07] 瀏覽器快取機制(http快取機制)
[深入08] 前端安全
[深入09] 深淺拷貝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模組化
[深入13] 觀察者模式 釋出訂閱模式 雙向資料繫結
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[react] Hooks

[部署01] Nginx
[部署02] Docker 部署vue專案
[部署03] gitlab-CI

前置知識

一些單詞

protocol:協議
permanent:永久的
permanently:永久地
temporary:暫時的
grammar:語法
複製程式碼

TCP/IP協議 - 應用層,傳輸層,網路層,資料鏈路層

  • 應用層:HTTP FTP TELNET SMTP DNS等協議
  • 傳輸層:TCP協議 UDP協議
  • 網路層:IP協議 ICMP協議等
  • 資料鏈路層

( TCP和UDP ) 傳輸層協議使用 ( IP協議 )網路層協議 從一個網路傳送資料包到另一個網路

  • 把 ( IP ) 想像成一種 ( 高速公路 ),它允許其它協議在上面行駛並找到到其它電腦的出口。
  • ( TCP和UDP ) 是高速公路上的 ( “卡車” )
  • 卡車攜帶的 ( 貨物 ) 就是像 ( HTTP ),檔案傳輸協議FTP這樣的協議

[深入17] HTTP 和 HTTPS

TCP首部圖解

[深入17] HTTP 和 HTTPS
[深入17] HTTP 和 HTTPS

  • 總結
    • Ack = Seq + 1 ---------------------- 確認號 = 序號 + 1
    • 序號Seq ( 簡稱ISN )
    • 確認號Ack
    • 標誌位:
      • SYN新建一個連結
      • FIN釋放一個連結
      • ACK為1時Seq序號才有效

TCP三次握手

三次握手:指的是建立TCP連結時,需要客戶端和服務端總的傳送的三個包

  • 第一次握手
    • 客戶端傳送一個 ( 標誌位SYN=1,序號Seq=x ) 的 ( 連線包 ) 到伺服器
      • SYN=1表示新建連結
      • 客戶端狀態:由 CLOSED狀態 => SYN_SENT狀態
  • 第二次握手
    • 伺服器傳送一個 ( 標誌位SYN=1,ACK=1,序號Seq=y,確認號Ack=x+1) 的 ( 確認包 ) 給客戶端
      • Ack = Seq + 1 ( 確認號 = 序號 + 1 )
      • 服務端狀態:由 CLOSED狀態 => SYN_RCVD狀態
  • 第三次握手
    • 客戶端傳送一個 ( 標誌位SYN=0,ACK=1,序號Seq=x+1,確認號Ack=y+1) 的 ( 確認包 ) 給伺服器
      • established:是建立的意思
      • 客戶端和服務端狀態都變成 ESTABLISHED 狀態

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

TCP建立連結 - 為什麼需要第三次握手

為什麼只有三次握手,才能確認雙方的傳送和接收能力是否正常,而兩次卻不可以??

  • 第一次握手:
    • 客戶端傳送連線包,服務端收到了
    • ( 服務端 ) 就能得出結論:( 客戶端的傳送能力,服務端的接收能力是正常的 )
  • 第二次握手
    • 服務端傳送確認包,客服端收到了
    • ( 客戶端 ) 就能得出結論:( 服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的 )
    • 注意:此時服務端並不能確認客戶端的接收能力是否正常
  • 第三次握手
    • 客戶端傳送確認包,服務端收到了
    • ( 服務端 ) 就能得出結論:( 客戶端的接收、傳送能力,和服務端的接收、傳送能力都是正常的 )
  • 總結為什麼需要三次握手
    • 為了實現可靠資料傳輸, TCP 協議的通訊雙方都必須維護一個序列號, 標識傳送出去的資料包哪些已經被對方收到
    • 三次握手的過程即是通訊雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟
    • 如果只是兩次握手, 至多隻有連線發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認,也就是上面每次握手分析的,如果兩次握手,服務端是沒法確認客戶端的接收能力是正常的
    • 防止已失效的連線請求又傳送到伺服器端,因而產生錯誤

四次揮手

  • 標誌位:FIN表示釋放一個連結
  • 注意:客戶端和服務端都可以主動發起揮手動作
  • established:建立的意思 ( ESTABLISHED )
  • 過程:( 假設由客戶端發起,標誌位FIN=1表示釋放連結 )
  • 第一次揮手
    • 客戶端傳送一個 ( 標誌位FIN=1,序號Seq=u ) 的 ( 釋放包 ) 到伺服器
    • 客戶端狀態:由 ESTABLISHED狀態 => FIN_WAIT1狀態
    • 表明的是:主動方(客戶端)的報文傳送完了,但是主動方(客戶端)還是可以接收報文
  • 第二次揮手
    • 伺服器返回一個 ( 標誌位ACK=1,確認號Ack=u+1,序號Seq=v ) 的 ( 確認包 ) 到客戶端
    • 服務端狀態:由 ESTABLISHED狀態 => COLSE_WAIT狀態
  • 第三次次揮手
    • 伺服器傳送一個 ( 標誌位FIN=1,ACK=1,確認號Ack=u+1,序號Seq=w ) 的 ( 釋放包 ) 到客戶端
    • 服務端狀態:由 COLSEWAIT狀態 => LAST_ACK狀態
    • 表明的是:主動方(服務端)的報文傳送完了,但是主動方(服務端)還是可以接收報文
  • 第四次次揮手
    • 客戶端送一個 ( 標誌位ACK=1,確認號Ack=w+1, 序號Seq=u+1 ) 的 ( 確認包 ) 到服務端
    • 客戶端狀態:由 FIN_WAIT2狀態 => TIME_WAIT狀態
  • 注意:
    • 客戶端通常是主動關閉,進入TIME_WAIT狀態
    • 服務端通常是被動關閉,不會進入TIME_WAIT狀態
      [深入17] HTTP 和 HTTPS

TIME_WAIT狀態 - 2MSL狀態

  • TIME_WAIT狀態也稱為2MSL等待狀態
  • 每個具體TCP實現必須選擇一個報文段最大生存時間MSL(Maximum Segment Lifetime),它是任何報文段被丟棄前在網路內的最長時間。

為什麼第四次揮手後,客戶端要進入TIME_WAIT狀態,而不是直接關閉

  • 因為要確保伺服器是否收到了Ack確認報文,即在2MSL時間內沒有再收到服務端的FIN報文,證明已經收到ACK
  • 如果沒有收到的話,伺服器會重新發 FIN 報文給客戶端,客戶端再次收到 ACK 報文之後,就知道之前的 ACK 報文丟失了,然後再次傳送 ACK 報文。
  • TIME_WAIT 持續的時間至少是一個報文的來回時間。一般會設定一個計時,如果過了這個計時沒有再次收到 FIN 報文,則代表對方成功就是 ACK 報文,此時處於 CLOSED 狀態。

一些重要的HTTP狀態碼

100 Continue ------------------------- 客戶端應繼續請求
101 Switching Protocols -------------- 切換協議,協議升級

200 ok ------------------------------- 請求被正常處理
204 no content ----------------------- 請求處理成功,但沒有資源可以返回
206 partial content ------------------ 請求部分資源

301 moved permanently ---------------- 永久重定向,需要變更書籤引用
302 Found ---------------------------- 臨時重定向
303 set other ------------------------ 臨時重定向,應採用 GET 方法獲取資源
304 not modified --------------------- 資源未被修改,協商快取
307 Temporary Redirect --------------- 臨時重定向

400 bad request ---------------------- 錯誤的請求
401 unauthorized --------------------- 認證失敗 ------------------------- (未授權)
403 forbidden ------------------------ 認證成功,但許可權不夠 ------------- (許可權不夠)
404 not found ------------------------ 資源未找到
405 method not allowed --------------- 請求方法錯誤

500 Internal Server Error ------------ 服務端錯誤
502 Bad Gateway ---------------------- 閘道器錯誤
503 Service Unavailable -------------- 伺服器過載
複製程式碼

HTTP

HTTP的缺點

  • 通訊使用 明文(不加密),內容可能會被 竊聽
  • 不驗證通訊方的 身份,因此有可能遭遇 偽裝
  • 無法證明報文的 完整性,所以有可能已遭 篡改

HTTP是 明文傳播,可能會遭到 竊聽
  • http本身不具備加密功能,報文使用明文傳播
  • 為什麼設計成不加密:
    • TCP/IP 協議族的工作機制,通訊內容在所有的通訊線路上都有 可能遭到窺視。
    • 即使已經過加密處理的通訊,也會被窺視到通訊內容,這點和未 加密的通訊是相同的。只是說如果通訊經過加密,就有可能讓人 無法破解報文資訊的含義,但加密處理後的報文資訊本身還是會 被看到的

加密的物件有哪些 - (加密處理防止被竊聽)

  • 通訊線路的加密 - 安全的通訊線路
  • 通訊內容的加密 - 內容有被篡改的風險

通訊線路的加密

  • http 通過和 SSL(secure socket layer 安全套接層) 或者和 TLS(transport layer security 安全層傳輸協議)的組合使用,來加密http的通訊內容

通訊內容的加密

  • 內容仍有被篡改的風險

HTTP不驗證通訊雙方的身份,可能會遭遇偽裝
  • HTTP 協議中的請求和響應不會對通訊方進行確認。
    • 伺服器是否就是傳送請求中 URI 真正指定的主機
    • 返回的響應是否真的返回到實際提出請求的客戶端,等類似問題。

不驗證通訊雙方的隱患

  • 無法確定響應的伺服器,就是要請求的目標伺服器
  • 無法確定響應內容是是否真正傳送給了請求時的客服端
  • 無法確定正在通訊的對方是否具備訪問許可權。如果Web伺服器上儲存著重要的資訊,只想發給特定使用者通訊的許可權。
  • 無法判定請求是來自何方、出自誰手
  • 即使是無意義的請求也會照單全收。無法阻止海量請求下的 DoS 攻擊(Denial of Service,拒絕服務攻擊)
  • 注意:http協議無法確定通訊方,但是SSL可以
    • SSL不僅提供加密處理,而且還使用了一種被稱為證書的手段, 可用於確定方
    • 證書由值得信任的第三方機構頒發,用以證明伺服器和客戶端是 實際存在的

[深入17] HTTP 和 HTTPS

HTTP無法驗證報文的完整性,可能會被篡改
  • 完整性指資訊的準確度
  • 接收到的內容可能有誤

什麼是中間人攻擊

  • 像這樣,請求或響應在傳輸途中,遭攻擊者攔截並篡改內容的攻擊稱為中間人攻擊
  • (Man-in-the-Middle attack,MITM)。

使用http協議確認確認報文完整性的方法

  • MD5 和 SHA-1 等雜湊值校驗的方法
  • 以及用來確認檔案的數字簽名方法。

HTTP報文 = 報文首部 + 空行 + 報文主體

請求報文首部 = 請求行 + 請求頭

響應報文首部 = 響應行 + 響應頭

  • 用於http協議互動的資訊被稱為http報文
  • 請求報文:客戶端的報文
  • 響應報文:服務端的報文
  • http報文:由多行資料構成的字串文字

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

HTTPS

HTTPS = HTTP + 加密 + 認證 + 完整性保護

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

  • ssl是獨立與http協議的,所以其他應用層的協議也可以使用ssl

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

HTTPS的加密方式 - 混合加密,即對稱加密和非對稱加密一起使用

  • https採用混合加密
    • 在交換金鑰環節:使用公開加密 - (非對稱加密)
    • 之後的建立通訊,交換報文階段:使用共享加密 - (對稱加密)
    • ( 非對稱加密 ) 的處理速度要比 ( 對稱加密 ) 慢,所以各有優勢,所以https採用組合加密

[深入17] HTTP 和 HTTPS

公開金鑰加密方式 - 無法證明公開金鑰本身就是貨真價實的公開金鑰

證明公開金鑰正確定的證書

  • 公開金鑰加密存在的問題
    • 無法證明公開金鑰就是貨真價實的公開金鑰, 因為公開金鑰在傳播過程中可能被替換
  • 問題:如何解決公開加密方式的公鑰的安全性 ?????
  • 解決:數字證書機構頒發的 ( 公開金鑰證書 )

數字證書機構的業務流程

  1. 伺服器申請公開金鑰證書
  2. 證書認證機構對已申請的 ( 公開金鑰 ) 做 ( 數字簽名 ),生成 ( 公鑰證書 )
  3. 伺服器將公鑰證書發給客戶端
  4. 客服端使用證書結構的 ( 公開金鑰 ) 對 ( 公鑰證書的數字簽名 ) 進行驗證
    • 驗證通過
      • 說明伺服器的公鑰是證書機構頒發的公鑰
      • 伺服器的公鑰值得信賴

[深入17] HTTP 和 HTTPS

[深入17] HTTP 和 HTTPS

https的通訊過程 - SSL握手過程

[深入17] HTTP 和 HTTPS

  • 名稱解釋:

    • handshake:握手
    • certificate:證書
    • cipher:密碼
    • Suite:一套
    • cipher suite:密碼元件
    • spec:規格
    • exchange:交換
    • ClientKeyExchange
    • ChangeCipherSpec:改變密碼規格,即非對稱加密交換公共金鑰後,使用對稱加密通訊
  • SSL握手過程 - 注意結合認證,組合加密一起來理解

  • (1) ( 客戶端 ) 通過傳送 ( client hello 報文 ) 開始 SSL 通訊

    • 報文中包含:( SSL版本 ),( 加密元件列表 )
    • 加密元件列表cipher suite包含:加密演算法,金鑰長度等
  • (2) ( 服務端 ) 傳送 ( erver Hello 報文 ) 作為應答

    • 報文中同樣包含:( SSL版本 ),( 加密元件列表 )
    • ( 伺服器 ) 的加密元件內容是從接收到的 ( 客戶端 ) 加密元件內 ( 篩選 ) 出來的
  • (3) ( 伺服器 ) 傳送 ( certificate ) 加密報文,報文中包含 ( 公開金鑰證書 )

  • (4) ( 伺服器 ) 傳送 ( Server Hello Done ) 報文通知客戶端,最初階段的 ( SSL握手協商,即第一次SSL握手結束 ) 部分結束

  • (5) 第一次SSL握手結束後,( 客戶端 ) 傳送 ( Client Key Exchange ) 報文作為回應

    • 報文中包含:Pre-Master secret 隨機密碼串,該報文使用3中的公共金鑰證書加密
  • (6) ( 客戶端 ) 繼續傳送 ( Change Cipher Spec ) 報文

    • 該報文會提示伺服器,在此報文之後的通訊會採用 Pre-master secret 金鑰加密
  • (7) ( 客戶端 ) 傳送 ( Finished ) 報文

    • 該報文包含連線至今,全部報文的整體校驗值
    • 這次握手協商是否成功,要以伺服器是否能夠正確解密該報文作為判斷標準
  • (8) ( 伺服器 ) 同樣傳送 ( Change Cipher Spec ) 報文

  • (9) ( 伺服器 ) 同樣傳送 ( Finished ) 報文

  • (10) 傳送HTTP請求,服務端和客戶端的Finished報文交換完畢之後,SSL連線就算建立完成,通訊會受到 SSL 保護

    • 從此處開始進行應用層的通訊,即傳送 HTTP 請求
  • (11) 響應HTTP請求

  • (12) 最後由客戶端斷開連線。斷開連線時,傳送 close_notify 報文。

url到頁面顯示過程

  1. DNS域名解析 // 將域名解析成IP地址
  2. 建立TCP連結 // 三次握手
  3. 客戶端發起HTTP請求
  4. 伺服器處理請求,並返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 斷開TCP連結 // 四次揮手
url到頁面顯示的過程


1. DNS域名解析
- DNS是 ( domain name system ) 域名系統的縮寫
- 將域名解析成ip地址
- 一個域名對應一個以上的ip地址
- 為什麼要將域名解析成ip地址?
    - 因 ( 為TCP/IP網路 ) 是通過 ( ip地址 ) 來確定 ( 通訊物件 ),不知道ip就無法將訊息傳送給對方
- DNS域名解析的過程:// 遞迴查詢和迭代查詢
1. ( 瀏覽器 ) 中查詢 DNS 快取,有則進入建立tcp連結階段,下面同理
2. ( 本機的系統 )中查詢 DNS 快取
3. ( 路由器 ) 中查詢 DNS 快取
4. ( 運營商伺服器 ) 中查詢 DNS 快取
5. 遞迴查詢 // 根域名/一級域名/二級域名 ....blog.baidu.com
    - .com
    - .baidu
    - blog
    - 還未找到就報錯



2. 建立tcp連結 // 三次握手
- 第一次握手
    - 客服端傳送一個 標誌位SYN=1,序號Seq=x的連結包給服務端
        - SYN:表示發起一個新連結,( Synchronize Sequence Numbers )
        - Seq:序號是隨機的
- 第二次握手
    - 服務端傳送一個 標誌位SYN=1,ACK=1,確認號Ack=x+1,序號Seq=y的確認包給客戶端
    - 標誌位 ACK 表示響應
- 第三次握手
    - 客戶端傳送一個 SYN=0,ACK=1,確認號Ack=y+1,序號Seq=x+1的確認包給伺服器
    - 為什麼需要三次握手
        - 之所以要第三次握手,主要是因為避免無效的連線包延時後又傳送到伺服器,造成伺服器以為又要建立連結的假象,造成錯誤
        
        
3. 客戶端傳送http請求
4. 服務端處理請求,並返回http響應報文


5. 瀏覽器解析渲染
  - 遇見HTML標記,瀏覽器呼叫HTML解析器,解析成Token並構建DOM樹
  - 遇見style/link標記,瀏覽器呼叫css解析器,解析成CSSOM樹
  - 遇見script標記,瀏覽器呼叫js解析器,處理js程式碼(繫結事件,可能會修改DOM tree 和 CSSOM tree)
  - 將DOM 和 CSSOM 合併成 render tree
  - 根據render tree計算佈局(佈局)
  - 將各個節點的顏色繪製到螢幕上(渲染)



6. 斷開TCP連結 // 四次揮手,( FIN : 表示釋放連結 )
- 第一次揮手:瀏覽器發起,告訴伺服器我請求報文傳送完了,你準備關閉吧
- 第二次揮手:伺服器發起,告訴瀏覽器我請求報文接收完了,我準備關閉了,你也準備吧
- 第三次揮手:伺服器發起,告訴瀏覽器,我響應報文傳送完了,你準備關閉吧
- 第四次揮手:瀏覽器發起,告訴伺服器,我響應報文接收完了,我準備關閉了,你也準備吧
- 先是伺服器先關閉,再是瀏覽器關閉
複製程式碼

TCP 和 UDP 的區別

  • TCP面向連結(可靠性高),UDP無連線(可靠性低)

[深入17] HTTP 和 HTTPS

HTTP1.0 和 HTTP1.1 的區別

HTTP1.0

  • 無狀態:伺服器不跟蹤不記錄請求過的狀態
  • 無連線:瀏覽器每次請求都要重新建立連結
HTTP1.0

(1) 無狀態
1. 伺服器不跟蹤記錄請求過的狀態
2. 對於無狀態的特性可以藉助 ( cookie/session ) 機制來做 ( 身份認證 ) 和 ( 狀態記錄 )

(2) 無連線
- 無連線導致的效能缺陷主要有兩種:
    - 無法複用連結
        - 每次傳送請求,都需要進行tcp連結,即三次握手和四次揮手,使得網路的利用率極低
    - 對頭阻塞
        - http1.0規定,在前一個請求響應到達之後,下一個請求才能傳送,如何前一個請求阻塞,後面的就都會阻塞
複製程式碼

HTTP1.1

HTTP1.1解決HTTP1.0的效能缺陷

  • 長連線:新增Connection欄位,可以設定 keep-alive 使保持連結不斷開
  • 管道化:基於長連線,管道化可以不等第一個請求響應,繼續傳送後面的請求,但是響應的順序還是要按請求的順序返回
  • 快取處理:新增 cache-control 欄位
  • 斷點續傳
HTTP1.1

(1) 長連線
- HTTP1.1預設保持長連線,資料傳輸完成,保持tcp連結不斷開,繼續使用這個通道傳輸資料

(2) 管道化
- http1.0
    - 請求1 > 響應1 --> 請求2 > 響應2 --> 請求3 > 響應3
- http1.1
    - 請求1 --> 請求2 --> 請求3 > 響應1 --> 響應2 --> 響應3
- 雖然管道化一次可以傳送多個請求,但響應仍然是順序返回,仍然無法解決對頭阻塞的問題

(3) 快取處理
- HTTP1.1新增 Cache-Control 欄位
    - http1.0  =>  expires           => 是一個絕對時間點,用GMT時間格式
    - http1.1  =>  Cache-Control     => 是一個相時時間段,以秒為單位
- Cache-control: no-cache,private,max-age=123123
    - no-cache:不使用強快取,使用協商快取
    - max-age: 一個時間段,單位是秒
    - public:允許所有伺服器快取該資源
    - private:表示該資源僅僅屬於發出請求的終端使用者,這將禁止中間伺服器(如代理伺服器)快取此類資源
               對於包含使用者個人資訊的檔案,可以設定private
- Expires 和 Cache-Control 對比
    - 如果同時開啟,Cache-Control 的優先順序高於 Expires
    - expires是一個用GMT時間表示的時間點,Cach-Control是用秒錶示的時間段,都是和瀏覽器本地時間做對比
    - Cache-Control 比 Expires 更加精確

(4) 斷點續傳
- 請求頭:Range
- 響應頭:Content-Range
- 原理
    - 在上傳/下載資源時,如果資源過大,將其分割為多個部分,分別上傳/下載
    - 如果遇到網路故障,可以從已經上傳/下載好的地方繼續請求,不用從頭開始,提高效率
複製程式碼

HTTP2.0

  • 二進位制分幀
  • 多路複用:在共享TCP連結的基礎上同時傳送請求和響應
  • 頭部壓縮
  • 伺服器推送:伺服器可以額外的向客戶端推送資源,而無需客戶端明確的請求
HTTP2.0

(1) 二進位制分幀
- 將所有傳輸的資訊分割為更小的訊息和幀,並對它們採用二進位制格式的編碼

(2) 多路複用
- 基於二進位制分幀
- 在同一域名下所有訪問都是從同一個tcp連線中走,http訊息被分解為獨立的幀,亂序傳送,服務端根據識別符號和首部將訊息重新組裝起來
複製程式碼

資料

HTTP和HTTPS簡介 juejin.im/post/5c6e58…
三次握手 juejin.im/post/5ca95e…
三次握手四次揮手 juejin.im/post/5cb932…
TCP報文 juejin.im/post/5a0444…
為什麼需要三次握手大白話 github.com/jawil/blog/…
四次揮手 juejin.im/post/5d9c28…
URL到頁面渲染 juejin.im/post/5c3401…
TCP和UDP:juejin.im/post/5a326c…
HTTP1.0 HTTP1.1 HTTP2.0 github.com/Advanced-Fr…
關於三次握手與四次揮手面試官想考我們什麼? juejin.im/post/5ccd0d…

相關文章