1 協議的基本概念
1-0 隊頭阻塞問題
TCP隊頭阻塞: TCP某個部分丟失,但是后續的數據不按序到達接收端的時候,由於TCP協議要保證有序性,其先達到的后續數據必須等待丟失數據重傳過來才能該將數據包交給應用層, 即HTTP2某個stream出現丟包時,該stream后續的包需要等待TCP重傳,那么就會影響其他stream(HTTP/3解決了用UDP+QUIC解決了TCP隊頭阻塞的問題)
HTTP1.1隊頭阻塞: 在HTTP/1.1中客戶端發送請求,服務器回應客戶端的請求,客戶端發送的每一個請求,需要等待服務器回應后才能發送下一個請求,即所有請求在一個FIFO隊列里,如果隊頭請求意外阻塞,這樣就會造成隊頭阻塞。即如果隊頭的請求響應時間太長,會影響后面的請求的處理(HTTP2用流和分幀的方式HTTP的隊頭阻塞問題)
緩解技術:
1)管道化:可以不等待上次請求的響應,直接發送下一個請求信息,但是客戶端仍然需要按照請求的順序處理響應,單個請求響應時間較長仍然會阻塞后續的請求,不能解決隊頭阻塞問題.
2)並發的TCP連接
1-1 http協議發展概述
協議的本質區分:安全性,性能問題
發展:http1.0+TCP => http1.1 + TLS/SSL+TCP => http2.0+TLS+TCP => http3.0+QUIC+UDP
協議名稱 | 性能 | 安全 | 缺陷 | 傳輸層協議 |
---|---|---|---|---|
http1.0 | TCP短連接,不支持斷點傳輸 | 無法解決竊聽,篡改,頂替問題,配合TLS協議 | TCP | |
http1.1 | TCP長連接(Connection:keep-alive),支持斷點續傳(Range) | 無法解決竊聽,篡改,頂替問題,配和TLS協議 | TCP | |
http2.0(主流網站使用配合TLS協議) | 頭部壓縮、⼆進制編碼、多路復⽤、服務器推送 | TLS(SSL)層解決竊聽,篡改,頂替問題 | TCP | |
http3.0 | 采用QUIC協議,該協議基於UDP保證可靠傳輸 | QUIC協議包含TLS | UDP |
HTTP 1.0 (1996年)
1)僅提供了最基本認證,用戶名及密碼未加密,不安全。
2)使用短連接,每次發送數據都會經過TCP三次握手和四次揮手,效率低。
3)只使用 header 中的 If-Modified-Since 和 Expires 作為緩存失效的標准。
4)不支持斷點續傳,每次都會傳送全部頁面和數據。
5)認為每台計算機只綁定一個IP,因此請求消息中的URL 並沒有傳遞主機名。
==================================================================
HTTP 1.1 (1999年)
1)使用摘要算法進行身份驗證
2)默認使用長連接,只需要建立一次連接就可以傳輸多次數據。連接時長通過請求頭中的 keep-alive來設置。
3)增加 E-tag,If-Unmodified-Since,If-Match,If-None-Match 等緩存控制標頭來控制緩存失效。
4)支持斷點續傳,通過使用請求頭中的 Range 來實現。
5) 使用虛擬網絡,可以支持虛擬機共享同一個IP地址。
======================================================================
HTTP 2.0 (2015年)
1)使用 HPACK 算法進行頭部壓縮,HTTP 1.1 會出現cookie、user-agent 等字段占用幾百個字節,導致頭部偏重。
2)使用二進制格式而非ASCII碼,提升了解析效率。
3)強化安全,HTTP 2.0 跑在 HTTPS 上。
4) 多路復用,每個請求都是作為連接共享,一個請求對應一個id,一個連接上可以多個請求。
=============================================================================\
HTTP3.0(最新)
HTTP/3 就將傳輸層從 TCP 替換成了 UDP,並在 UDP 協議上開發了 QUIC 協議,來保證數據的可靠傳輸。
QUIC 協議的特點:
1)⽆隊頭阻塞, QUIC 連接上的多個 Stream 之間並沒有依賴,都是獨⽴的,也不會有底層協議限制,某個流發
⽣丟包了,只會影響該流,其他流不受影響;
2)建⽴連接速度快,因為 QUIC 內部包含 TLS1.3,因此僅需 1 個 RTT 就可以「同時」完成建⽴連接與 TLS 密鑰
協商,甚⾄在第⼆次連接的時候,應⽤數據包可以和 QUIC 握⼿信息(連接信息 + TLS 信息)⼀起發送,達到
0-RTT 的效果。
3)連接遷移, QUIC 協議沒有⽤四元組的⽅式來“綁定”連接,⽽是通過「連接 ID 」來標記通信的兩個端點,客戶
端和服務器可以各⾃選擇⼀組 ID 來標記⾃⼰,因此即使移動設備的⽹絡變化后,導致 IP 地址變化了,只要仍保有上下⽂信息(⽐如連接 ID、 TLS 密鑰等),就可以“⽆縫”地復⽤原連接,消除重連的成本;
4)另外 HTTP/3 的 QPACK 通過兩個特殊的單向流來同步雙⽅的動態表,解決了 HTTP/2 的 HPACK 隊頭阻塞問題。
1-2 http協議頭部常用字段
1-2-1 實際字段信息
General
Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 180.101.49.11:443
Referrer Policy: strict-origin-when-cross-origin
1)請求url,
2)請求方法,
3)狀態碼,
4)遠程服務器IP地址:端口號,
5)Referrer Policy:用於控制請求頭中的referrer字段顯示的信息,這個字段用於顯示當前的請求是是從哪個頁面發起該請求的
比如:在某網站點擊外部鏈接跳轉,那么不同策略最終得到的跳轉頁面的referrer字段顯示的信息也是不同的。
- 5)的策略通常從安全和隱私的角度設置,更多參考HTTP請求中的referrer和Referrer-Policy
Request Headers
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0 # 默認資源有效期為0即每次都重新請求(chrome瀏覽器特性)
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
Cookie: BIDUPSID=AC40325179B6B61E75468AC472209C14; PSTM=1630076261; BAIDUID=AC40325179B6B61E0605129DD7DC3488:FG=1; BD_UPN=12314753; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; __yjs_duid=1_f4dfa29776139c045828bf93c4ea919c1630295908965; BDSFRCVID_BFESS=Pn0OJeC62RiLby3H-WQ6UOtXH8_S9r7TH6ao-EetxyN9kucQCyPwEG0PEf8g0KAbl_9MogKK0eOTHk-F_2uxOjjg8UtVJeC6EG0Ptf8g0f5; H_BDCLCKID_SF_BFESS=tbut_KDMJDK3j-_kh4nb-P4ObqKX5-RLfaRXop7F5l8-hxoYX-5BDUvD3nLqLxRJyg-OMM8X-D3xOKQphIcpbJ0b2tI8abQ2Lm78bP3N3KJmsJL9bT3vLtDjBNru2-biWbR-2Mbd256P_IoG2Mn8M4bb3qOpBtQmJeTxoUJ25DnJhbLGe4bK-TryeHuj3J; H_PS_645EC=ee61Y%2FHwA96Y7VOPX5mUVVoNu0XFjTjZ3dQBaa0co6HvSsx6R7dcV2%2B%2FLqaPmfcuzg; BD_HOME=1; H_PS_PSSID=34439_34497_31254_33848_34092_34107_26350_34418_34473; BA_HECTOR=8ga02l00840l248ksm1gj1l650q
Response Headers
HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0x93ba5c8f000078e1
Cache-Control: private # 客戶端可以緩存
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Thu, 02 Sep 2021 13:42:55 GMT
Expires: Thu, 02 Sep 2021 13:41:58 GMT # 資源過期時間
Server: BWS/1.1
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=34439_34497_31254_33848_34092_34107_26350_34418_34473; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1630590175279410689010644922438493698273
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
1-2-2 常用字段信息分類以及作用
- 總體上可以分為3個類別,客戶端信息,消息體的信息,緩存設置
a)客戶端信息相關字段:包括host,瀏覽器標識(User-Agent)
b)消息體相關字段:內容長度,類型,編碼(壓縮)方式
c)強緩存控制字段:cache-control.exprie
d)協商緩存控制字段:Etag,If-modified
字段名稱 | 屬性說明 | 應用場景 | 屬性值 |
---|---|---|---|
Host | 服務器的域名 | 服務端根據host字段來確定客戶端將訪問的網站路徑 | |
User-Agent | 多個公司的瀏覽器標識,如:Mozilla、Chrome、Safari,也包含多個渲染引擎標識 | 聚合掃碼服務,可以根據每個app的user-agent字段確定掃碼app類型 | 瀏覽器的常見User Agent 各字段的解釋 |
Content-Length | 響應內容長度 | 根據這個字段獲取響應消息體的內容 | |
Connection | 持久連接設置字段 | 客戶端要求服務器使⽤ TCP 持久連接,以便其他請求復⽤。 | keep-live |
Content-Type | 內容類型 | 客戶/服務端根據這個字段確定內容的類型,並采用對應的解碼方式 | 可選值 |
Content-Encoding/Accept-Encoding | 內容壓縮方法設置 | 客戶端根據Content-Encoding確定解壓方式,通過Accept-Encoding告知解壓方法 | gzip |
expires | 緩存過期的時間(1.0字段,1.1使用cache-control:max-age取代該字段)服務端可以通過該字段告知返回資源的有效期 | 強制緩存字段 | |
cache-control | 在緩存未失效時候,瀏覽器向服務端發起請求,直接從緩存中獲取數據, | 強制緩存字段 | private, public, nocache, max-age, nostore |
If-modified-Since(Last-Modified) | 資源最后修改的時間 | 對比緩存使用 | |
Etag(Entity Tag) | 根據實體內容計算的hash值,用於標記當前資源是否改變 |
知識點:對比緩存(協商緩存)
核心思想:客戶端請求攜帶Last-Modified和Etag字段,服務端校驗這兩個字段進行返回*,如果無需更新則返回304,否則返回修改后的資源。
對比緩存定義:服務器對比判斷文件是否修改,告訴瀏覽器是否可以使用本地緩存。對比生效時,服務器返回給瀏覽器的http code 為304,服務器只返回http header信息,並無響應正文。瀏覽器收到304的返回,知道本地緩存並無修改,直接使用本地緩存。
--------------------------------------------------------------------------------------------------------
對比緩存對比流程:
瀏覽器請求資源
服務器返回Last-Modified/If-Modified-Since和Etag
瀏覽器緩存Last-Modified/If-Modified-Since和Etag在本地
瀏覽器再次請求資源,請求頭包含If-Modified-Since/If-None-Match
服務器再次計算資源的Last-Modified和Etag,並和瀏覽器傳過來的比較
如不相同,資源發生變化,返回Http code 200,並且返回資源。如相同,返回http code 304,不需要返回資源。
---------------------------------------------------------------------------------------------------------
對比緩存何時使用?
對於瀏覽器來說的話,一般會在強制緩存過期的情況下,如果資源原先的響應header中帶有Last-Modified和Etag的話,瀏覽器請求時會在請求header中帶上If-Modified-Since和If-None-Match。
------------------------------------------------------------
Etag是否可以替代If-Modified-Since?
可以,但是對於緩存一致性要求不是太高的場景,If-modfied-Since可以節約hash計算開銷
Etag比lastModified更加嚴謹,如果資源發生變化,Etag就會發生變化,就會把最新的資源給客戶端返回去,而lastModified不識別s(秒)單位里的修改,所以如果資源在s(秒)單位里發生了修改,那lastModified也不會發生改變,這樣如果只用了lastModified,客戶端得到的資源就不是最新的;但是設定了Etag之后,每次客戶端發出請求,服務端都會根據資源重新生成一個Etag,對性能有影響
注意:對比緩存通常與強緩存一起使用
1-3 Http常見狀態碼
RFC文檔共定義了5類狀態碼:
- Informational responses (
100
–199
) - Successful responses (
200
–299
) - Redirects (
300
–399
) - Client errors (
400
–499
) - Server errors (
500
–599
)
1)信息提示信息: 100(Continue)表示客戶端應該繼續請求
2) 成功響應信息: 200(OK),206(Partial Content)
3) 重定向信息:
--301(Moved Permanently): 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI
--302(Found):臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI
--304(Not Modified):緩存信息提示,表示請求的資源沒有修改
--305(Use Proxy):使用代理。所請求的資源必須通過代理訪問
4) 客戶端錯誤:
--403(Forbidden):服務器理解請求客戶端的請求,但是拒絕執行此請求
--404(Not Found)
--410(Gone):請求資源被移除
5) 服務端錯誤:
500 Internal Server Error 服務器內部錯誤,無法完成請求
501 Not Implemented 服務器不支持請求的功能,無法完成請求
502 Bad Gateway 作為網關或者代理工作的服務器嘗試執行請求時,從遠程服務器接收到了一個無效的響應
503 Service Unavailable 由於超載或系統維護,服務器暫時的無法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中
504 Gateway Time-out 充當網關或代理的服務器,未及時從遠端服務器獲取請求
505 HTTP Version not supported 服務器不支持請求的HTTP協議的版本,無法
http超時設置
瀏覽器有默認連接超時,Firefox 好像是115秒,Chrome 好像是5分鍾還是6分鍾。如果后端需要處理十多分鍾才能返回結果,那肯定是要異步返回結果。不可能同步,沒理由同步,就算瀏覽器不超時,你也沒必要同步返回,浪費資源。要及時返回處理結果,你可以用 WebSocket 和 Ajax 輪詢實現。用戶上傳文件,服務器成功接受文件后返回一個上傳成功的結果,然后前端給個 Loading 提示,然后定時輪詢,查詢后端處理結果,處理成功了就更新前端提示成功,沒有就繼續 Loading 提示。
2 協議安全問題
2-1 http協議安全概述(三個風險的解決策略)
http明文傳輸帶來的問題
- 竊聽⻛險:個人隱私信息可被其他人獲取(比如自己的家庭地址,手機號,父母姓名等)
- 篡改⻛險:收到的數據可能被第三方修改過,或被植入廣告等(截住數據包在http的body添加內容在發給接受方,http劫持,運營商劫持)。
- 冒充風險:訪問的站點非目標服務器站點。釣魚網站(CA證書)。
- https 被劫持: 客戶單安裝偽造的CA 證書,被代理服務器劫持。沒有認證的證書,客戶端選擇信任。
HTTPS | ||
---|---|---|
竊聽風險(泄密) | 混合加密(對稱+非對稱) | |
篡改風險(劫持) | 摘要算法(本質是哈希函數) | |
冒充風險(冒充) | CA證書(服務器公鑰放⼊到數字證書 ) |
知識點1:CA證書如何確保服務器的公鑰是可靠的(冒充風險)?
HTTPS體系中若攻擊者將自己公鑰上傳CA得到簽名,並將兩者一起用於篡改證書的中間人攻擊會怎樣
- 關鍵對象:瀏覽器,服務器,證書頒發機構(CA, Certificate Authority)(CA服務器)
- 核心:瀏覽器與服務器必須保證證書頒發機構可靠(CA的私匙不會被泄漏)
問題:CA證書的檢驗的流程
1) 服務器向CA注冊公匙
2)CA用自己的私匙對服務端公鑰進行加密,並放入到數字證書中,頒發給服務端
3)客戶端拿到服務端數字證書后,使用CA服務器提供的公鑰進行解密並校驗數字簽名,沒有問題則獲取到服務端公鑰,
- 可靠性依賴於認證機構
知識點2:DNS協議的安全問題
DNS劫持:修改域名解析的結果(比如修改操作系統的域名文件將IP地址進行替換)
劫持方法:控制域名解析流程中任意環節都能夠實現DNS劫持
====================================================================================
瀏覽器域名解析的流程:
1)首先搜索瀏覽器的 DNS 緩存(各種瀏覽器有固定值),緩存中維護一張域名與 IP 地址的對應表
2)若沒有命中,則繼續搜索操作系統的 DNS 緩存(C:\Windows\System32\drivers\etc\hosts)
3)若仍然沒有命中,則操作系統將域名發送至本地域名服務器,本地域名服務器查詢自己的 DNS 緩存,查找成功則返回結果(注意:主機和本地域名服務器之間的查詢方式是遞歸查詢);
====================================================================================
4)若本地域名服務器的 DNS 緩存沒有命中,則本地域名服務器向上級域名服務器進行查詢,通過以下方式進行迭代查詢(注意:本地域名服務器和其他域名服務器之間的查詢方式是迭代查詢,防止根域名服務器壓力過大):
5)首先本地域名服務器向根域名服務器發起請求,根域名服務器是最高層次的,它並不會直接指明這個域名對應的 IP 地址,而是返回頂級域名服務器的地址,也就是說給本地域名服務器指明一條道路,讓他去這里尋找答案
本地域名服務器拿到這個頂級域名服務器的地址后,就向其發起請求,獲取權限域名服務器的地址
本地域名服務器根據權限域名服務器的地址向其發起請求,最終得到該域名對應的 IP 地址
============================================================================
6)本地域名服務器將得到的 IP 地址返回給操作系統,同時自己將 IP 地址緩存起來
7)操作系統將 IP 地址返回給瀏覽器,同時自己也將 IP 地址緩存起來
8)至此,瀏覽器就得到了域名對應的 IP 地址,並將 IP 地址緩存起來
====================================================================================
遞歸查詢和迭代查詢的使用場景:
主機->本地域名服務器使用遞歸查詢的原因如下:
1)本地域名服務器負責一片地區的域名解析,需要對DNS記錄進行緩存
2)通常服務器的數量不是太多,壓力比較小。
本地域名服務器向根域名服務器的查詢的迭代查詢的原因
1)根域名數量稀少,每次請求都自己獲取結果頂不住
2)頂級域名服務器在收到本地域名服務器的查詢請求后,要么給出所要查詢的IP地址,要么告訴本地服務器下一步應當向哪一個權限域名服務器進行查詢。
DNS污染(欺騙):當你的電腦向域名服務器發送了“域名查詢”的請求,然后域名服務器把回應發送給你的電腦,這之間是有一個時間差的。如果某個攻擊者能夠在域名服務器的“DNS應答”還沒有到達你的電腦之前,先偽造一個錯誤的“DNS應答”發給你電腦。那么你的電腦收到的就是錯誤的信息,並得到一個錯誤的 IP地址。
知識點3:DNS底層協議的變更歷史
1)當年內容貧乏,硬件性能低下。認為主機查詢的動作頻次低,數據量少。用TCP短連結握手和揮手的開銷比查詢還高。用長連接服務器又承受不住。UDP是很好的選擇(開銷小)
2)互聯網起來后DNS頻率急劇增加,所以又加上了TCP版本(內容多)。
3)隨着惡意的DNS污染出現后,DNS又升級了TLS版本(網上壞蛋多)
一般情況:DNS既用UDP也用TCP,大部分情況下是UDP,根據長度使用TCP,根據實際需求來
2-2 https協議訪問博客園主頁流程分析(TLS1.2抓包分析)
概述
從抓包的信息來看,博客園使用http2.0協議+TLS協議實現通信。
2-2-1 TLS協議預備知識
- 下面是TLS四次握手過程中第一次握手的信息(Client Hello信息)
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 2f1be521a6026fc823d215486c851fe49b4e02cf622eff058e28593097ed7362
GMT Unix Time: Jan 17, 1995 23:41:21.000000000 中國標准時間
Random Bytes: a6026fc823d215486c851fe49b4e02cf622eff058e28593097ed7362
Session ID Length: 32
Session ID: bd4eb383ad1bfb074dd591e58d5fd49b7ce3e6cd91001af9c6e18501fbd074a6
Cipher Suites Length: 32
Cipher Suites (16 suites)
Cipher Suite: Reserved (GREASE) (0x3a3a)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: null (0)
Extensions Length: 403
Extension: Reserved (GREASE) (len=0)
Extension: server_name (len=20)
Extension: extended_master_secret (len=0)
Extension: renegotiation_info (len=1)
Extension: supported_groups (len=10)
Extension: ec_point_formats (len=2)
Extension: session_ticket (len=0)
Extension: application_layer_protocol_negotiation (len=14)
Extension: status_request (len=5)
Extension: signature_algorithms (len=18)
Extension: signed_certificate_timestamp (len=0)
Extension: key_share (len=43)
Extension: psk_key_exchange_modes (len=2)
Extension: supported_versions (len=11)
Extension: compress_certificate (len=3)
Extension: Unknown type 17513 (len=5)
Extension: Reserved (GREASE) (len=1)
Extension: padding (len=196)
TLS協議字段比較重要的字段 | 說明 |
---|---|
Content Type | 內容類型(Handshake,Change Cipher Spec,Application Data) |
Random | 客戶端產生的隨機數 |
Session ID | 會話ID |
Cipher Suites(16種供服務端選擇) | 密碼套件 |
Compression Methods | 壓縮方法 |
Extensions | 擴展字段 |
cipher [ˈsaɪfər]:密碼 suites[swi:ts] :套件
TLS的子協議有哪些(消息類型)
TLS 握手協議又細分為四個子協議,分別是握手協議、密碼規格變更協議、警告協議和應用數據協議。
----------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22) # 握手協議
---------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 74
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 70
Version: TLS 1.2 (0x0303)
------------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 300
Handshake Protocol: Server Key
.........
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0
-----------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 37
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 33
EC Diffie-Hellman Client Params
Pubkey Length: 32
Pubkey: 9794d9fb624442d8fe38422e66f75fb238b7bf7711261180e5ce6258f9f71d11
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20) # 密碼規格變更
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message
-----------------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Application Data Protocol: http2
Content Type: Application Data (23) # 應用數據
Version: TLS 1.2 (0x0303)
Length: 94
Encrypted Application Data: 00000000000000010330a080c236d86aae91be7f0035145f74bd9f2d245ec4528b37e72a…
[Application Data Protocol: http2]
-----------------------------------------------------------------------------------
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: New Session Ticket
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 202
Handshake Protocol: New Session Ticket
Handshake Type: New Session Ticket (4)
Length: 198
TLS Session Ticket
Session Ticket Lifetime Hint: 300 seconds (5 minutes)
Session Ticket Length: 192
Session Ticket: 6b493048344b6c62545630734b58616746b035cebe98b47299f98db9e76ea5214b0e2e75…
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message
https協議中密碼套件內容
- 下圖是TLS第二次握手返回的信息(服務端的Server Hello信息)
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 74
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 70
Version: TLS 1.2 (0x0303)
Random: 2b3e737287f120241fbf1c4ff1595e3b5c028795d69a0e47cc0d806cf9aee080
GMT Unix Time: Dec 28, 1992 11:24:34.000000000 中國標准時間
Random Bytes: 87f120241fbf1c4ff1595e3b5c028795d69a0e47cc0d806cf9aee080
Session ID Length: 0
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
密碼套件的內容
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
密匙交換算法ECDHE+服務器證書的簽名算法類型(RSA類型簽名算法) + 對稱加密算法(AES_128,分組模式是GCM) + hash算法(SHA256)
注意:
1)證書是RSA的,則就可以支持RSA的簽名算法,如果是ECDSA的證書,則可以支持ECDSA的簽名算法
密匙協商的定義:密鑰協商(key establishment)包括“密鑰傳輸”(key transmission)和“密鑰交換”(key exchange)。
密匙協商DH算法背后的數學思想
數學原理:離散對數
底數a和模數p是離散對數的公共參數,i是對數,b是真數
知道對數i很容易計算真數b,但知道真數b很難獲知對數i => b作為公鑰,i作為私匙
注意:當模數 p 是⼀個很⼤的質數,即使知道底數 a 和真數 b ,在現有的計算機的計算⽔平是⼏乎⽆法算出離散
對數的,這就是 DH 算法的數學基礎。
密匙協商算法DH(Diffie-Hellman)計算出對稱加密密匙作為會話密鑰使⽤流程
加密雙方:bob和Alice
step1: bob和Alice首先進行通信約定2個參數即模數P和底數G作為DH算法的公共參數,並各⾃⽣成⼀個隨機整數作為DH算法的私鑰
step2:bob和Alice使用2個公共參數與自己的私鑰匙各自計算出對應的公鑰A和B
step3:再次通信交換DH算法公鑰
step4:使用對方提供的DH算法公鑰和自己的私匙,利用離散對數的冪運算有交換律,計算出相同的會話密匙也就是對稱加密密匙K
獲取會話密匙的注意點:
1)雙方需要約定公共參數
2)雙方需要交換DH算法公匙
DH算法分類
分類依據:根據私鑰的分類方式
- static DH:有⼀⽅的私鑰是靜態的,也就說每次密鑰協商的時候有⼀⽅的私鑰都是⼀樣的,⼀般是服務器⽅固定,即 a 不變,客戶端的私鑰則是隨機⽣成的。
static DH缺點:存在安全隱患,沒有前向安全性
DH 交換密鑰時就只有客戶端的公鑰是變化,⽽服務端公鑰是不變的,那么隨着時間延⻓,⿊客就會截獲海
量的密鑰協商過程的數據,因為密鑰協商的過程有些數據是公開的,⿊客就可以依據這些數據暴⼒破解出服務器的
私鑰,然后就可以計算出會話密鑰了,於是之前截獲的加密數據會被破解,所以 static DH 算法不具備前向安全
性。
- DHE 算法, E 全稱是 ephemeral(臨時性的)
DHE算法缺點:計算開銷較大
固定⼀⽅的私鑰有被破解的⻛險,那么⼲脆就讓雙⽅的私鑰在每次密鑰交換通信時,都是隨機⽣成的、臨時
的,這個⽅式也就是 DHE 算法, E 全稱是 ephemeral(臨時性的)。
ephemeral: [ɪˈfɛmərəl]
- ECDHE 算法
在 DHE 算法的基礎上利⽤了 ECC 橢圓曲線特性,可以⽤更少的計算量計算出公鑰,以及最終的會話密鑰。
⼩紅和⼩明使⽤ ECDHE 密鑰交換算法的過程:
1) 雙⽅事先確定好使⽤哪種橢圓曲線,和曲線上的基點 G,這兩個參數都是公開的;
2) 雙⽅各⾃隨機⽣成⼀個隨機數作為私鑰d,並與基點 G相乘得到公鑰Q(Q = dG),此時⼩紅的公私鑰為 Q1和 d1,⼩明的公私鑰為 Q2 和 d2;
3) 雙⽅交換各⾃的公鑰,最后⼩紅計算點(x1, y1) = d1Q2,⼩明計算點(x2, y2) = d2Q1,由於橢圓曲線
上是可以滿⾜乘法交換和結合律,所以 d1Q2 = d1d2G = d2d1G = d2Q1 ,因此雙⽅的 x 坐標是⼀樣的,所以
它是共享密鑰,也就是會話密鑰。
4) 這個過程中,雙⽅的私鑰都是隨機、臨時⽣成的,都是不公開的,即使根據公開的信息(橢圓曲線、公鑰、基點
G)也是很難計算出橢圓曲線上的離散對數(私鑰)。
采用RSA和ECDHE進行密匙協商對於加密連接建立影響
12501 31.146350 49.52.10.139 101.37.115.180 TLSv1.2 571 Client Hello
12505 31.157473 101.37.115.180 49.52.10.139 TCP 60 443 → 4608 [ACK] Seq=1 Ack=518 Win=30720 Len=0
12506 31.160535 101.37.115.180 49.52.10.139 TLSv1.2 1434 Server Hello
12507 31.161218 101.37.115.180 49.52.10.139 TLSv1.2 1434 Certificate [TCP segment of a reassembled PDU]
12508 31.161218 101.37.115.180 49.52.10.139 TLSv1.2 319 Server Key Exchange, Server Hello Done
12509 31.161283 49.52.10.139 101.37.115.180 TCP 54 4608 → 443 [ACK] Seq=518 Ack=3026 Win=131072 Len=0
12517 31.190495 49.52.10.139 101.37.115.180 TLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
----------------------------------------------------------------------------------
12518 31.190825 49.52.10.139 101.37.115.180 TLSv1.2 153 Application Data
---------------------------------------------------------------------------------
12519 31.191459 49.52.10.139 101.37.115.180 TCP 1434 4608 → 443 [ACK] Seq=710 Ack=3026 Win=131072 Len=1380 [TCP segment of a reassembled PDU]
12520 31.191459 49.52.10.139 101.37.115.180 TLSv1.2 1361 Application Data
12521 31.202447 101.37.115.180 49.52.10.139 TLSv1.2 312 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
-------------------------------------------------------------------------------------
12522 31.203126 101.37.115.180 49.52.10.139 TLSv1.2 123 Application Data
- 上面抓包流程中在12519之前即在 TLS 第四次握⼿前,客戶端就已經發送了加密的 HTTP 數據(說明客戶端/服務端已經獲取到了會話密匙),⽽對於 RSA 握⼿過程,必須要完成 TLS 四次握⼿,才能傳輸應⽤數據
ECDHE 相⽐ RSA 握⼿過程省去了⼀個消息往返的時間,這個有點「搶跑」的意思,它被稱為是「TLS
False Start」,跟「TCP Fast Open」有點像,都是在還沒連接完全建⽴前,就發送了應⽤數據,這樣便提⾼了傳
輸的效率。
密鑰協商算法總結
目的:用於TLS/SSL四次握手過程中協商對稱密鑰
密鑰協商(key establishment)包括“密鑰傳輸”(key transmission)和“密鑰交換”(key exchange)。
用於進行密匙協商的算法 | 安全性 | 特點 |
---|---|---|
RSA | 無前向安全性 | 使⽤ RSA 密鑰交換算法的 TLS 握⼿過程,不僅慢,⽽且安全性也不⾼。 |
DH | 無前向安全性 | |
DHE | 前向安全 | |
ECDHE | 前向安全 | 該算法由於⽀持可以讓客戶端搶跑,在 TLS 協議的第 3 次握⼿后就可以發送應用數據 |
RSA算法與DH系列算法的本質區別:
RSA算法:作用是Key Transmission(密匙傳輸),用於產生Session Key的“種子”是由客戶端決定,用服務器的公鑰加密並再次傳輸到服務器端。
DH算法:作用是密匙交換,DH算法一定是配合對稱加密算法使用,對稱加密算法工作前必須必須確保雙方持有會話密匙,DH算法通過雙發的隨機數交換利用離散對數的交換律可以直接計算出對稱加密的鑰匙。
總結如下:
1) RSA 密鑰協商算法「不⽀持」前向保密, ECDHE 密鑰協商算法「⽀持」前向保密;
2) 使⽤了 RSA 密鑰協商算法, TLS 完成四次握⼿后,才能進⾏應⽤數據傳輸,⽽對於 ECDHE 算法,客戶端可以不⽤等服務端的最后⼀次 TLS 握⼿,就可以提前發出加密的 HTTP 數據,節省了⼀個消息的往返時間;
3) 使⽤ ECDHE, 在 TLS 第 2 次握⼿中,會出現服務器端發出的「Server Key Exchange」消息,⽽ RSA 握⼿過程沒有該消息
2-2-2 TLS建立加密通信的流程
step1:建立TCP連接即三次握手
抓包分析:
瀏覽器發起TCP連接,可以看到:
1)本地瀏覽器IP地址為49.52.10.139,使用的端口號為4608
2)博客園網站的公網IP為101.37.115.180,使用端口為443
注意:443為https協議常用的端口
step2: TLS四次交互(2RTT:Round-Trip Time))
- 采用EDCH的密匙協商算法,公鑰是算出來的
step1:客戶端向服務端發起加密通信握手請求,也就是Client Hello信息
主要信息包括:協議版本,密碼套件等的約定
(1)客戶端⽀持的 SSL/TLS 協議版本,如 TLS 1.2 版本。
(2)客戶端⽣產的隨機數( Client Random ),后⾯⽤於⽣產「會話秘鑰」。
(3)客戶端⽀持的密碼套件列表,如 RSA 加密算法。
step2:服務端響應加密通信的請求,返回server Hello信息
主要信息包括服務端最終選擇密碼套件以及版本等信息,還有最重要的就是服務端證書和用於產生會話密匙的協商算法所需要的協商算法公鑰信息。
(1)確認 SSL/ TLS 協議版本,如果瀏覽器不⽀持,則關閉加密通信。
(2)服務器⽣產的隨機數( Server Random ),后⾯⽤於⽣產「會話秘鑰」。
(3)確認的密碼套件列表,如 RSA 加密算法。
(4)服務器的數字證書CA
step3:客戶端收到服務器的響應,校驗CA證書並從證書中獲取公匙,后續簽名信息都會用證書中的公匙加密,並且計算出會話密匙,然后服務端所需要的用於產生會話密匙的協商算法所需要的協商算法公鑰信息。
step4:服務端收到計算會話密匙所需要的信息后,然后響應表示自己准備好了加密通信所需要的會話密匙,發「Change Cipher Spec」和「Encrypted Handshake Message」消息.
注意:上面的流程是基於ECDH協商算法生成會話密匙的流程,基於RSA協商算法的流程會有所區別
https四次交互的流程梳理
四次通信梳理:
1)第一次往返后,客戶端與服務端約定好協議版本,密碼套件,客戶端獲取CA證書並校驗從而拿到服務端的RSA公匙,該公共鑰匙會最為簽名信息的加密密匙
2)第二次往返后,客戶端與服務端要計算出會話密匙(比如AES128的對稱加密密匙),用於加密傳輸的數據。
問題:TLS加密通信連接建立的過程中三次隨機數的作用?
最終的會話密鑰,就是⽤「客戶端隨機數 + 服務端隨機數 + x(ECDHE 算法算出的共享密鑰) 」三個材料⽣成
的。
傳輸隨機數的動機:TLS 設計者不信任客戶端或服務器「偽隨機數」的可靠性,為了保證真正的完全隨機,
把三個不可靠的隨機數混合起來,那么「隨機」的程度就⾮常⾼了,⾜夠讓⿊客計算出最終的會話密鑰,安全性更
⾼
2-2-3 基於ECDH的TLSv1.2的建立流程抓包信息
可以參考小林coding的圖解網絡書籍,寫的非常不錯
抓包分析
編號 | 時間 | 本地瀏覽器 | 博客園服務器 | 協議 | 消息長度 | 信息 |
---|
12489 31.131823 49.52.10.139 101.37.115.180 TCP 66 4608 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
12499 31.143002 101.37.115.180 49.52.10.139 TCP 66 443 → 4608 [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1380 SACK_PERM=1 WS=512
12500 31.143109 49.52.10.139 101.37.115.180 TCP 54 4608 → 443 [ACK] Seq=1 Ack=1 Win=131072 Len=0
12501 31.146350 49.52.10.139 101.37.115.180 TLSv1.2 571 Client Hello
12505 31.157473 101.37.115.180 49.52.10.139 TCP 60 443 → 4608 [ACK] Seq=1 Ack=518 Win=30720 Len=0
12506 31.160535 101.37.115.180 49.52.10.139 TLSv1.2 1434 Server Hello
12507 31.161218 101.37.115.180 49.52.10.139 TLSv1.2 1434 Certificate [TCP segment of a reassembled PDU]
12508 31.161218 101.37.115.180 49.52.10.139 TLSv1.2 319 Server Key Exchange, Server Hello Done
12509 31.161283 49.52.10.139 101.37.115.180 TCP 54 4608 → 443 [ACK] Seq=518 Ack=3026 Win=131072 Len=0
12517 31.190495 49.52.10.139 101.37.115.180 TLSv1.2 147 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
12518 31.190825 49.52.10.139 101.37.115.180 TLSv1.2 153 Application Data
12519 31.191459 49.52.10.139 101.37.115.180 TCP 1434 4608 → 443 [ACK] Seq=710 Ack=3026 Win=131072 Len=1380 [TCP segment of a reassembled PDU]
12520 31.191459 49.52.10.139 101.37.115.180 TLSv1.2 1361 Application Data
12521 31.202447 101.37.115.180 49.52.10.139 TLSv1.2 312 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
12522 31.203126 101.37.115.180 49.52.10.139 TLSv1.2 123 Application Data
12523 31.203126 101.37.115.180 49.52.10.139 TLSv1.2 92 Application Data
握手過程中的抓包提示信息
瀏覽器->博客園:1) Client Hello
博客園->瀏覽器:2) Server Hello
Certificate [TCP segment of a reassembled PDU]
Server Key Exchange, Server Hello Done
瀏覽器->博客園:3) Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
Application Data
博客園->瀏覽器 4) New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
總結:TLS1.2協議由於ECDH算法特性,實際上第三次交互,客戶端就可以發送數據給服務端了。
session Ticket的作用:
知識點:TCP segment of a reassembled PDU的含義
基於TCP在傳輸消息時,對於上面的應用層如果出於某些原因(如超過MSS)TCP Segment不能一次包含全部的應用層PDU,而要把一個完整消息分成多個段,就會將除了最后一個分段(segment)的所有其他分段都打上“TCP segment of a reassembled PDU”
2-2-4 TLS協議的發展
起源
SSL(Secure Sockets Layer)與TLS(Transport Layer Security)本質上一個東西,一個是標准化前的名稱,一個是標准化后的名稱。
TLS1.3對TLS1.2的優化
上圖是TLS1.2和TLS1.3的區別
- 1)TLS1.3優化了TLS1.2過程,只需要 1 個 RTT 往返時延,也就是只需要3次握⼿
TLS1.3默認只支持ECDH密匙協商算法!!!!!!。因此不需要像TLS1.2一樣,通過hello的應答信息確定密匙協商算法,所有在第一次交互中將hello信息與公鑰交互的信息合並發送,從而減少了一次握手
- 2)TLS1.3支持更少的密碼套件
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
TLS_AES_128_CCM_8_SHA256
TLS_AES_128_CCM_SHA256
動機:安全考量
2-2-5 https的優化策略
策略1:TLS連接的會話復用
動機:⾸次 TLS 握⼿協商的對稱加密密鑰緩存起來,待下次需要建⽴ HTTPS 連接時,直接「復⽤」這個密鑰,不就減少 TLS 握⼿的性能損耗
會話復⽤分采用兩種機制實現:
第⼀種叫 Session ID;
第⼆種叫 Session Ticket;
Session ID 的⼯作原理:
客戶端和服務器⾸次 TLS 握⼿連接后,雙⽅會在內存緩存會話密鑰,並⽤唯⼀的Session ID 來標識, Session ID 和會話密鑰相當於 key-value 的關系。當客戶端再次連接時, hello 消息⾥會帶上 Session ID,服務器收到后就會從內存找,如果找到就直接⽤該會話密鑰恢復會話狀態,跳過其余的過程,只⽤⼀個消息往返就可以建⽴安全通信。當然為了安全性,內存中的會話密鑰會定期失效。
缺點:1)多個連接的多個ID引入服務器的內存開銷 2)負載均衡導致連接的服務器未必是同一服務器,id未必有效
Session Ticket:服務器不再緩存每個客戶端的會話密鑰,⽽是把緩存的工作交給了客戶端
----------------------------------------------------------------------------------------------------------
原理:客戶端與服務器⾸次建⽴連接時,服務器會加密「會話密鑰」作為 Ticket 發給客戶端,交給客戶端緩存該 Ticket。客戶端再次連接服務器時,客戶端會發送 Ticket,服務器解密后就可以獲取上⼀次的會話密鑰,然后驗證有效期,如果沒問題,就可以恢復會話了,開始加密通信。
-----------------------------------------------------------------------------------------------------------
注意:有點類似於token與session信息的維護
3 http2.0協議簡介
3-1 協議設計動機
網站數據傳輸需求變化:消息變大,資源的內容樣式更加多 => 對請求與響應的延遲有了更加嚴格的性能要求
針對http1.1的延遲以及連接上限問題問題,從具體的技術層面有以下的技巧優化:
1) 多張⼩圖合並成⼀張⼤圖供瀏覽器 JavaScript 來切割使⽤,這樣可以將多個請求合並成⼀個請求,但是帶來了新的問題,當某張⼩圖⽚更新了,那么需要重新請求⼤圖⽚,浪費了⼤量的⽹絡帶寬(減少資源數目過多引發的請求開銷),類似機制比如多個體積較⼩的 JavaScript ⽂件使⽤ webpack 等⼯具打包成⼀個體積更⼤的 JavaScript ⽂件。同樣某個js⽂件變化,需要重新請求同⼀個包⾥的所有js⽂件。
2) 圖⽚的⼆進制數據通過base64編碼后,把編碼數據嵌⼊到HTML或CSS⽂件中,以此來減少⽹絡請求次數(作為文本后,瀏覽器不需要另外再去請求圖片資源,圖片直接作為文本給傳輸過來)
3)將同⼀個⻚⾯的資源分散到不同域名,提升並發連接上限,因為瀏覽器通常對同⼀域名的 HTTP 連接最⼤只能是6個
知識點:使用base64編碼圖片的動機
優點:1)減少了HTTP請求 2)某些文件可以避免跨域的問題 3)沒有圖片更新要重新上傳,還要清理緩存的問題
缺點:1)根據 base64 的編碼原理,編碼后的大小會比原文件大小大 1/3 ,如果把大圖片編碼到
html/css 中,不僅會造成文件體積的增加,影響文件的加載速度,還會增加瀏覽器對 html 或 css 文件解析渲染的時間。
2)使用 base64 無法直接緩存,要緩存只能緩存包含 base64 的文件,比如 HTML 或者 CSS ,
這相比域直接緩存圖片的效果要差很多
3)兼容性的問題,ie8以前的瀏覽器不支持。一般一些網站的小圖標可以使用 base64 圖片來引入。
------------------------------------------------------------------------------------------------------------------
使用base64編碼需要考慮三點:
1)編碼資源是否需要緩存
2)減少http請求是否很有必要
3)瀏覽器的兼容性需要考慮
3-2 協議優化點
特點 | 實現 | |
---|---|---|
頭部壓縮 | HPACK 算法, HPACK 算法主要包含三個組成部分:靜態字典;動態字典;Huffman 編碼(壓縮算法),http1.1可以采用gzip壓縮資源 | 傳輸數據壓縮 |
⼆進制幀 | 數據壓縮 | |
並發傳輸 | 多個 Stream 復⽤⼀條 TCP 連接,同一stream通過stream ID亂序傳輸(TCP特性,單個流的數據丟失會影響其他流) | 應用層隊頭阻塞問題解決 |
服務器主動推送資源 | 客戶端發起的請求,必須使⽤的是奇數號 Stream,服務器主動的推送,使⽤的是偶數號 Stream。服務器在推送源時,會通過 PUSH_PROMISE 幀傳輸 HTTP 頭部,並通過幀中的 Promised Stream ID 字段告知客戶端,接下來會在哪個偶數號 Stream 中發送包體 |
問題:http1.1和http2.0的隊頭阻塞問題的區別?
本質區別:1.1是應用層的隊頭阻塞,而2.0是傳輸層的隊頭阻塞
http2.0的隊頭阻塞問題:HTTP/2 是基於 TCP 協議來傳輸數據的, TCP 是字節流協議, TCP 層必須保證收到的字節數據是完整且連續的,
這樣內核才會將緩沖區⾥的數據返回給 HTTP 應⽤,那么當「前 1 個字節數據」沒有到達時,后收到的字節數據只能存放在內核緩沖區⾥,只有等到這 1 個字節數據到達時, HTTP/2 應⽤層才能從內核中拿到數據,這就是HTTP/2 隊頭阻塞問題。
4 http3.0協議
3-1 設計動機
http2.0的設計動機回顧:
對http1.1的性能進行優化:采用頭部壓縮、⼆進制編碼、多路復⽤、服務器推送
http2.0在性能上仍然存在以下問題:傳輸層隊頭阻塞,TLS握手延遲,網絡遷移開銷
http2.0使用的是TCP,由於TCP本身的特性,帶來下面問題:
1) 隊頭阻塞:TCP在設計上通過序號機制保證了數據的有序性,因此如果低位序號丟失,那么高位序列數據也無法被應用層獲取,這一定程度造成了阻塞。
2) TCP 與 TLS 的握⼿時延遲:(三次握手+四次加密通信請求握手,3個RTT延遲)
3) ⽹絡遷移需要重新連接:一個TCP連接是通過四元組確定,因此 IP 地址或者端⼝變動了,就會導致需要 TCP 與 TLS 重新握⼿,這不利於移動設備切換⽹絡的場景,⽐如 4G ⽹絡環境切換成WIFI。
http2.0的問題本質:TCP協議的設計所限制
3-2 QUIC協議
QUIC 協議:基於 UDP 協議在「應⽤層」實現
QUIC | HTTP2 | |
---|---|---|
⽆傳輸層或者應用層的隊頭阻塞 (流與流之間沒有影響,影響限制在單個流) | HTTP/2 只要某個流中的數據包丟失了,其他流也會因此受影響。 | |
更快連接建⽴(QUIC 內部包含了 TLS ) | TLS與TCP都需要分別建立連接 | |
連接遷移 (通過上下⽂信息(連接 ID、 TLS 密鑰等),就可以“⽆縫”地復⽤原連接,消除重連的成本) | TCP基於四元組 |
QUIC 協議的特點:
- ⽆隊頭阻塞, QUIC 連接上的多個 Stream 之間並沒有依賴,都是獨⽴的,也不會有底層協議限制,某個流發
⽣丟包了,只會影響該流,其他流不受影響; - 建⽴連接速度快,因為 QUIC 內部包含 TLS1.3,因此僅需 1 個 RTT 就可以「同時」完成建⽴連接與 TLS 密鑰
協商,甚⾄在第⼆次連接的時候,應⽤數據包可以和 QUIC 握⼿信息(連接信息 + TLS 信息)⼀起發送,達到
0-RTT 的效果。 - 連接遷移, QUIC 協議沒有⽤四元組的⽅式來“綁定”連接,⽽是通過「連接 ID 」來標記通信的兩個端點,客戶
端和服務器可以各⾃選擇⼀組 ID 來標記⾃⼰,因此即使移動設備的⽹絡變化后,導致 IP 地址變化了,只要仍
保有上下⽂信息(⽐如連接 ID、 TLS 密鑰等),就可以“⽆縫”地復⽤原連接,消除重連的成本;
3-3 http3.0的特點
http3.0直接使用QUIC提供的數據幀,因此更加數據幀簡單
HTTP/3 在頭部壓縮算法升級HPACK為QPACK。HTTP/3 中的 QPACK 也采⽤了靜態表、動態表及 Huffman 編碼, QPACK 通過兩個特殊的單向流來同步雙⽅的動態表,解決了 HTTP/2 的 HPACK 隊頭阻塞問題。
特點:動態表的優化
動態表,在⾸次請求-響應后,雙⽅會將未包含在靜態表中的 Header 項更新各⾃的動態表,接着后續傳輸時
僅⽤ 1 個數字表示,然后對⽅可以根據這 1 個數字從動態表查到對應的數據,就不必每次都傳輸⻓⻓的數據,⼤⼤
提升了編碼效率。可以看到, 動態表是具有時序性的,如果⾸次出現的請求發⽣了丟包,后續的收到請求,對⽅就⽆法解碼出
HPACK 頭部,因為對⽅還沒建⽴好動態表,因此后續的請求解碼會阻塞到⾸次請求中丟失的數據包重傳過來。
HTTP/3 的 QPACK 解決了這⼀問題,那它是如何解決的呢?QUIC 會有兩個特殊的單向流,所謂的單項流只有⼀端可以發送消息,雙向則指兩端都可以發送消息,傳輸 HTTP
消息時⽤的是雙向流,這兩個單向流的⽤法:⼀個叫 QPACK Encoder Stream, ⽤於將⼀個字典(key-value)傳遞給對⽅,⽐如⾯對不屬於靜態表的
HTTP 請求頭部,客戶端可以通過這個 Stream 發送字典;⼀個叫 QPACK Decoder Stream,⽤於響應對⽅,告訴它剛發的字典已經更新到⾃⼰的本地動態表了,后續就
可以使⽤這個字典來編碼了。這兩個特殊的單向流是⽤來同步雙⽅的動態表,編碼⽅收到解碼⽅更新確認的通知后,才使⽤動態表編碼 HTTP 頭部。
更多說明參考尾部鏈接02
Wireshark簡單使用
常用單條過濾命令
http請求相關
http.request.method=="GET"
http.request.method=="POST"
ip地址過濾
ip.dst==49.52.10.41
ip.src==10.15.112.61
ip.addr==xxx.xxx.xxx.xxx # 同時過濾
端口過濾:協議+端口號
tcp.srcport==80
tcp.dstport==80
組合命令
http.request.method=="GET"and tcp.port==80 # 過濾出GET方法並且端口是80