【網絡通信 -- 直播】IM 學習系列 -- 網絡通信協議簡介(HTTP 協議 六)

【網絡通信 -- 直播】IM 學習系列 -- 網絡通信協議簡介(HTTP 協議 六)

【1】HTTPS 相關概念簡介

【1.1】安全的通信過程需要具備四個特性,即機密性、完整性,身份認證和不可否認
機密性(Secrecy/Confidentiality)是指對數據的“保密”,只能由可信的人訪問,對其他人是不可見的“祕密”,簡單來說就是不能讓不相關的人看到不該看的東西;
完整性(Integrity,也叫一致性)是指數據在傳輸過程中沒有被篡改,不多也不少,“完完整整”地保持着原狀;
身份認證(Authentication)是指確認對方的真實身份,保證消息只能發送給可信的人;
不可否認(Non-repudiation/Undeniable),也叫不可抵賴,意思是不能否認已經發生過的行爲;

【1.2】HTTPS (默認端口號 443)

HTTPS 把 HTTP 下層的傳輸協議由 TCP/IP 換成了 SSL/TLS,由“HTTP over TCP/IP”變成了“HTTP over SSL/TLS”,讓 HTTP 運行在了安全的 SSL/TLS 協議上,收發報文不再使用 Socket API,而是調用專門的安全接口

【1.3】SSL/TLS
SSL 即安全套接層(Secure Sockets Layer),在 OSI 模型中處於第 5 層(會話層),由網景公司於 1994 年發明,有 v2 和 v3 兩個版本;SSL 發展到 v3 時已經證明了它自身是一個非常好的安全通信協議,於是互聯網工程組 IETF 在 1999 年把它改名爲 TLS(傳輸層安全,Transport Layer Security),正式標準化,版本號從 1.0 重新算起,所以 TLS1.0 實際上就是 SSLv3.1;
TLS 由記錄協議、握手協議、警告協議、變更密碼規範協議、擴展協議等幾個子協議組成,綜合使用了對稱加密、非對稱加密、身份認證等許多密碼學前沿技術
瀏覽器和服務器在使用 TLS 建立連接時需要選擇一組恰當的加密算法來實現安全通信,這些算法的組合被稱爲“密碼套件”(cipher suite,也叫加密套件)
TLS 的密碼套件命名格式很固定,基本的形式是“密鑰交換算法 + 簽名算法 + 對稱加密算法 + 摘要算法”,如ECDHE-RSA-AES256-GCM-SHA384表示握手時使用 ECDHE 算法進行密鑰交換,用 RSA 簽名和身份認證,握手後的通信使用 AES 對稱算法,密鑰長度 256 位,分組模式是 GCM,摘要算法 SHA384 用於消息認證和產生隨機數
OpenSSL 一個著名的開源密碼學程序庫和工具包,幾乎支持所有公開的加密算法和協議,已經成爲了事實上的標準

【2】對稱加密與非對稱加密

實現機密性最常用的手段是“加密”(encrypt),即將消息用某種方式轉換成不易理解的亂碼,只有掌握密鑰才能再轉換出原始文本;加密前的消息叫“明文”(plain text/clear text),加密後的亂碼叫“密文”(cipher text),使用密鑰還原明文的過程叫“解密”(decrypt),是加密的反操作,加密解密的操作過程就是“加密算法”;
由於 HTTPS、TLS 都運行在計算機上,所以“密鑰”就是一長串的數字,並且度量單位是“位”(bit),而不是“字節”(byte);

【2.1】對稱加密

“對稱加密”即加密和解密時使用的密鑰都是同一個,是“對稱”的,只要保證了密鑰的安全,那整個通信過程就具有了機密性;

TLS 裏有非常多的對稱加密算法可供選擇,比如 RC4、DES、3DES、AES、ChaCha20 等,但前三種算法都被認爲是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20;

AES 即“高級加密標準”(Advanced Encryption Standard),密鑰長度可以是 128、192 或 256,它是 DES 算法的替代者,安全強度很高,性能也很好,而且有的硬件還會做特殊優化,是應用最廣泛的對稱加密算法;
ChaCha20 是 Google 設計的另一種加密算法,密鑰長度固定爲 256 位,純軟件運行性能要超過 AES,曾經在移動客戶端上比較流行,但 ARMv8 之後也加入了 AES 硬件優化,所以現在不再具有明顯的優勢,但仍然算得上是一個不錯的算法;

加密分組模式
對稱算法還有一個“分組模式”的概念,它可以讓算法用固定長度的密鑰加密任意長度的明文,把密鑰轉化爲密文,最早有 ECB、CBC、CFB、OFB 等幾種分組模式,但都陸續被發現有安全漏洞,所以現在基本都不怎麼用了;最新的分組模式被稱爲 AEAD(Authenticated Encryption with Associated Data),在加密的同時增加了認證的功能,常用的是 GCM、CCM 和 Poly1305;
把上面這些組合起來,就可以得到 TLS 密碼套件中定義的對稱加密算法,比如,AES128-GCM,意思是密鑰長度爲 128 位的 AES 算法,使用的分組模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 算法,使用的分組模式是 Poly1305;

【2.2】非對稱加密
對稱加密中有一個很大的問題,即如何把密鑰安全地傳遞給對方,術語叫“密鑰交換”;在對稱加密算法中只要持有密鑰就可以解密,如果你和網站約定的密鑰在傳遞途中被黑客竊取,那他就可以在之後隨意解密收發的數據,通信過程也就沒有機密性可言了;
非對稱加密(也叫公鑰加密算法),它有兩個密鑰,一個叫“公鑰”(public key),一個叫“私鑰”(private key),兩個密鑰是不同的,公鑰可以公開給任何人使用,而私鑰必須嚴格保密,公鑰和私鑰有個特別的“單向”性,雖然都可以用來加密解密,但公鑰加密後只能用私鑰解密,反過來,私鑰加密後也只能用公鑰解密;
非對稱加密可以解決“密鑰交換”的問題,網站祕密保管私鑰,在網上任意分發公鑰,你想要登錄網站只要用公鑰加密就行了,密文只能由私鑰持有者才能解密,而黑客因爲沒有私鑰,所以就無法破解密文;


非對稱加密算法在 TLS 裏只有很少的幾種,比如 DH、DSA、RSA、ECC 等;
RSA 的安全性基於“整數分解”的數學難題,使用兩個超大素數的乘積作爲生成密鑰的材料,想要從公鑰推算出私鑰是非常困難的;10 年前 RSA 密鑰的推薦長度是 1024,但隨着計算機運算能力的提高,現在 1024 已經不安全,普遍認爲至少要 2048 位;
ECC(Elliptic Curve Cryptography)基於“橢圓曲線離散對數”的數學難題,使用特定的曲線方程和基點生成公鑰和私鑰,子算法 ECDHE 用於密鑰交換,ECDSA 用於數字簽名;
對比 RSA,ECC 在安全強度和性能上都有明顯的優勢,160 位的 ECC 相當於 1024 位的 RSA,而 224 位的 ECC 則相當於 2048 位的 RSA,因爲密鑰短,所以相應的計算量、消耗的內存和帶寬也就少,加密解密的性能高;

【2.3】混合加密

TLS 的混合加密方式
1. 在通信剛開始的時候使用非對稱算法,比如 RSA、ECDHE,首先解決密鑰交換的問題;
2. 用隨機數產生對稱算法使用的“會話密鑰”(session key),再用公鑰加密,因爲會話密鑰很短,通常只有 16 字節或 32 字節,所以慢一點也無所謂;
3. 對方拿到密文後用私鑰解密,取出會話密鑰,這樣,雙方就實現了對稱密鑰的安全交換,後續就不再使用非對稱加密,全都使用對稱加密;

【3】數字簽名與證書

【3.1】摘要算法

實現完整性的手段主要是摘要算法(Digest Algorithm),即散列函數、哈希函數(Hash Function),可以把摘要算法近似地理解成一種特殊的壓縮算法,其能夠把任意長度的數據“壓縮”成固定長度、而且獨一無二的“摘要”字符串,就好像是給這段數據生成了一個數字“指紋”;也可以把摘要算法理解成特殊的“單向”加密算法,它只有算法,沒有密鑰,加密後的數據無法解密,不能從摘要逆推出原文;

摘要算法需要處理“衝突”的可能性並且具有“單向性”和“雪崩效應”,輸入的微小不同會導致輸出的劇烈變化;
常見的摘要算法: 
MD5(Message-Digest 5) 能夠生成 16 字節長度的數字摘要;
SHA-1(Secure Hash Algorithm 1),能夠生成 20 字節長度的數字摘要;
SHA-2 是一系列摘要算法的統稱,總共有 6 種,常用的有 SHA224、SHA256、SHA384,分別能夠生成 28 字節、32 字節、48 字節的摘要;

【3.2】數字簽名

實現“身份認證”和“不可否認”的手段主要是“數字簽名”,即使用私鑰再加上摘要算法;
數字簽名的原理是把公鑰私鑰的用法反過來,即私鑰加密、公鑰解密;由於非對稱加密效率太低,因此私鑰只加密原文的摘要,這樣運算量就小的多,而且得到的數字簽名也很小,方便保管和傳輸;簽名和公鑰一樣完全公開,任何人都可以獲取;但這個簽名只有用私鑰對應的公鑰才能解開,拿到摘要後,再比對原文驗證完整性;

【3.3】數字證書和 CA

“公鑰的信任”問題需要確認一個公認的可信第三方,讓其作爲“信任的起點,遞歸的終點”,構建起公鑰的信任鏈,即 CA(Certificate Authority,證書認證機構);它具有極高的可信度,由它來給各個公鑰簽名,用自身的信譽來保證公鑰無法僞造,是可信的;
CA 對公鑰的簽名認證的格式包含序列號、用途、頒發者、有效時間等等,把這些打成一個包再簽名,完整地證明公鑰關聯的各種信息,形成“數字證書”(Certificate);知名的 CA 有 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它們簽發的證書分 DV、OV、EV 三種,區別在於可信程度;其中,DV 是最低的,只是域名級別的可信;EV 是最高的,經過了法律和審計的嚴格覈查,可以證明網站擁有者的身份;

【3.3.1】CA 的認證

【3.3.2】證書體系的弱點
1. CA 失誤或者被欺騙,簽發了錯誤的證書,雖然證書是真的,可它代表的網站卻是假的;
2. CA 被黑客攻陷或者 CA 有惡意,因爲它(即根證書)是信任的源頭,導致整個信任鏈裏的所有證書都不可信;
對策,針對第一種,開發出了 CRL(證書吊銷列表,Certificate revocation list)和 OCSP(在線證書狀態協議,Online Certificate Status Protocol),及時廢止有問題的證書;對於第二種,因爲涉及的證書太多,就只能操作系統或者瀏覽器撤銷對 CA 的信任,列入“黑名單”,這樣它頒發的所有證書就都會被認爲是不安全的;

【4】TLS1.2 連接過程解析

【4.1】TLS 協議的組成
TLS 包含 記錄協議、警報協議、握手協議、變更密碼規範協議等子協議;
記錄協議(Record Protocol)規定了 TLS 收發數據的基本單位即記錄(record),所有的其他子協議都需要通過記錄協議發出,但多個記錄數據可以在一個 TCP 包裏一次性發出,也並不需要像 TCP 那樣返回 ACK;
警報協議(Alert Protocol)的職責是向對方發出警報信息,有點像是 HTTP 協議裏的狀態碼;比如,protocol_version 是不支持舊版本,bad_certificate 是證書有問題,收到警報後另一方可以選擇繼續,也可以立即終止連接;
握手協議(Handshake Protocol),瀏覽器和服務器會在握手過程中協商 TLS 版本號、隨機數、密碼套件等信息,然後交換證書和密鑰參數,最終雙方協商得到會話密鑰,用於後續的混合加密系統;
變更密碼規範協議(Change Cipher Spec Protocol),實質是一個“通知”,告訴對方,後續的數據都將使用加密保護,那麼反過來,在它之前,數據都是明文的;

下面的這張圖簡要地描述了 TLS 的握手過程,其中每一個“框”都是一個記錄,多個記錄組合成一個 TCP 包發送,最多經過兩次消息往返(4 個消息)就可以完成握手,然後就可以在安全的通信環境裏發送 HTTP 報文,實現 HTTPS 協議;

【4.2】ECDHE 握手過程

【4.3】RSA 握手過程

【4.4】雙向認證
雙向認證的流程只是在“Server Hello Done”之後,“Client Key Exchange”之前,客戶端要發送“Client Certificate”消息,服務器收到後也把證書鏈走一遍,驗證客戶端的身份;

【5】TLS1.3特性解析

TLS1.3 的三個主要改進目標:兼容、安全與性能
最大化兼容性
TLS1.3 保持現有的記錄格式不變,通過“僞裝”來實現兼容,使得 TLS1.3 看上去“像是”TLS1.2使用新的擴展協議(Extension Protocol)可以區分 1.2 和 1.3,通過在記錄末尾添加一系列的“擴展字段”來增加新的功能,老版本的 TLS 不認識它可以直接忽略,這就實現了“後向兼容”;在記錄頭的 Version 字段被兼容性“固定”的情況下,只要是 TLS1.3 協議,握手的“Hello”消息後面就必須有“supported_versions”擴展,它標記了 TLS 的版本號,使用它就能區分新舊協議;

Handshake Protocol: Client Hello
    Version: TLS 1.2 (0x0303)
    Extension: supported_versions (len=11)
        Supported Version: TLS 1.3 (0x0304)
        Supported Version: TLS 1.2 (0x0303)

強化安全
改進方面如 1.僞隨機數函數由 PRF 升級爲 HKDF(HMAC-based Extract-and-Expand Key Derivation Function);2. 明確禁止在記錄協議裏使用壓縮;3. 廢除了 RC4、DES 對稱加密算法;4. 廢除了 ECB、CBC 等傳統分組模式;5. 廢除了 MD5、SHA1、SHA-224 摘要算法;6. 廢除了 RSA、DH 密鑰交換算法和許多命名曲線;
TLS1.3 裏只保留了 AES、ChaCha20 對稱加密算法,分組模式只能用 AEAD 的 GCM、CCM 和 Poly1305,摘要算法只能用 SHA256、SHA384,密鑰交換算法只有 ECDHE 和 DHE,橢圓曲線只保留 P-256 和 x25519 等 5 種;

提升性能
利用擴展,客戶端在“Client Hello”消息裏直接用“supported_groups”帶上支持的曲線,比如 P-256、x25519,用“key_share”帶上曲線對應的客戶端公鑰參數,用“signature_algorithms”帶上簽名算法;服務器收到後在這些擴展裏選定一個曲線和參數,再用“key_share”擴展返回服務器這邊的公鑰參數,就實現了雙方的密鑰交換;

握手分析

【6】HTTPS的優化

HTTPS 連接大致上可以劃分爲兩個部分,第一個是建立連接時的非對稱加密握手,第二個是握手後的對稱加密報文傳輸;
“HTTPS 連接慢”指的就是剛開始建立連接的那段時間,在 TCP 建連之後,正式數據傳輸之前,HTTPS 比 HTTP 增加了一個 TLS 握手的步驟,這個步驟最長可以花費兩個消息往返,即 2-RTT;而在握手消息的網絡耗時之外,還會有其他的一些“隱形”消耗,比如:產生用於密鑰交換的臨時公私鑰對(ECDHE);驗證證書時訪問 CA 獲取 CRL 或者 OCSP;非對稱加密解密處理“Pre-Master”;

【6.1】硬件優化

HTTPS 連接是計算密集型,而不是 I/O 密集型
1. 選擇更快的 CPU,最好還內建 AES 優化,這樣即可以加速握手,也可以加速傳輸;
2. 選擇“SSL 加速卡”,加解密時調用它的 API,讓專門的硬件來做非對稱加解密,分擔 CPU 的計算壓力;
3. “SSL 加速服務器”,用專門的服務器集羣來徹底“卸載”TLS 握手時的加密解密計算;

【6.2】協議優化
1. 採用 TLS1.3,它大幅度簡化了握手的過程,完全握手只要 1-RTT,而且更加安全;
2. 如果暫時不能升級到 1.3,只能用 1.2,那麼握手時使用的密鑰交換協議應當儘量選用橢圓曲線的 ECDHE 算法,它不僅運算速度快,安全性高,還支持“False Start”,能夠把握手的消息往返由 2-RTT 減少到 1-RTT,達到與 TLS1.3 類似的效果;
3. 橢圓曲線也要選擇高性能的曲線,最好是 x25519,次優選擇是 P-256;
4. 對稱加密算法方面,可以選用“AES_128_GCM”,它比“AES_256_GCM”略快一點點;

【6.3】證書優化
服務器的證書可以選擇橢圓曲線(ECDSA)證書而不是 RSA 證書,因爲 224 位的 ECC 相當於 2048 位的 RSA,即能夠節約帶寬也能減少客戶端的運算量;
客戶端的證書的驗證其實是個很複雜的操作,除了要公鑰解密驗證多個證書籤名外,因爲證書還有可能會被撤銷失效,客戶端有時還會再去訪問 CA,下載 CRL 或者 OCSP 數據,這又會產生 DNS 查詢、建立連接、收發數據等一系列網絡通信,增加好幾個 RTT;
CRL(Certificate revocation list,證書吊銷列表)由 CA 定期發佈,裏面是所有被撤銷信任的證書序號,查詢這個列表就可以知道證書是否有效,但 CRL 因爲是“定期”發佈,就有“時間窗口”的安全隱患,而且隨着吊銷證書的增多,列表會越來越大,一個 CRL 經常會上 MB,因此基本不用了;
OCSP(在線證書狀態協議,Online Certificate Status Protocol),向 CA 發送查詢請求,讓 CA 返回證書的有效狀態,但 OCSP 也要多出一次網絡請求的消耗,而且還依賴於 CA 服務器,如果 CA 服務器很忙,那響應延遲也是等不起的;
“OCSP Stapling”(OCSP 裝訂),它可以讓服務器預先訪問 CA 獲取 OCSP 響應,然後在握手時隨着證書一起發給客戶端,免去了客戶端連接 CA 服務器查詢的時間;

【6.4】會話複用
1. “Session ID”,就是客戶端和服務器首次連接後各自保存一個會話的 ID 號,內存裏存儲主密鑰和其他相關的信息;當客戶端再次連接時發一個 ID 過來,服務器就在內存裏找,找到就直接用主密鑰恢復會話狀態,跳過證書驗證和密鑰交換,只用一個消息往返就可以建立安全通信;

2. “Session Ticket”,存儲的責任由服務器轉移到了客戶端,服務器加密會話信息,用“New Session Ticket”消息發給客戶端,讓客戶端保存;重連的時候,客戶端使用擴展“session_ticket”發送“Ticket”而不是“Session ID”,服務器解密後驗證有效期,就可以恢復會話,開始加密通信;

【6.5】預共享密鑰
“Pre-shared Key”,在發送 Ticket 的同時會帶上應用數據(Early Data),免去了服務器確認步驟,但“PSK”爲了追求效率而犧牲了一點安全性,容易受到“重放攻擊”(Replay attack)的威脅,黑客可以截獲“PSK”的數據,反覆向服務器發送;解決的辦法是隻允許安全的 GET/HEAD 方法,在消息里加入時間戳、“nonce”驗證,“一次性票證”限制重放;

參考致謝
本博客爲博主的學習實踐總結,並參考了衆多博主的博文,在此表示感謝,博主若有不足之處,請批評指正。

【1】透視HTTP協議

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章