網(wǎng)絡安全篇,面對復雜多變的網(wǎng)絡環(huán)境蔽氨,我們需要掌握哪些關于網(wǎng)絡安全的相關知識暮刃,聊一聊與網(wǎng)絡安全相關的:HTTPS跨算、SSL、TLS 等椭懊。
網(wǎng)絡安全專題
- 網(wǎng)絡安全的基石
《網(wǎng)絡安全 — HTTPS》
《網(wǎng)絡安全的基石(上)— 加密》
《網(wǎng)絡安全的基石(下)— 完整性與身份認證》
《公鑰信任問題 — 數(shù)字證書與 CA》
《信任始于握手 — TLS 連接過程詳解》
- HTTPS 的優(yōu)化
《TLS 1.3 特性解析》
《如何優(yōu)化 HTTPS 連接》- 待完善
TLS 協(xié)議的組成
在介紹 TLS 握手之前诸蚕,我們先來簡單介紹下 TLS 協(xié)議的組成。
TLS 實際由若干不同職責的模塊組成氧猬,比較常用的有握手協(xié)議背犯、變更密碼規(guī)范協(xié)議、警報協(xié)議和記錄協(xié)議等盅抚。
從體系結構圖可以看出漠魏,SSL/TLS 協(xié)議可分為兩層:握手協(xié)議和記錄協(xié)議。
握手協(xié)議
握手協(xié)議用來協(xié)商會話參數(shù)(如會話密鑰妄均、應用層協(xié)議等)柱锹。它實際由若干不同職責的子模塊組成,比較常用的有握手協(xié)議丰包、變更密碼規(guī)范協(xié)議禁熏、警報協(xié)議和記錄協(xié)議等。
- 握手協(xié)議(Handshake Protocol)
建立在 SSL 記錄協(xié)議之上邑彪,是 TLS 里最復雜的子協(xié)議瞧毙,要比 TCP 的 SYN/ACK 復雜的多。用于在實際傳輸數(shù)據(jù)之前寄症,通訊雙方進行身份認證升筏、協(xié)商加密算法、交換會話密鑰瘸爽,用于后續(xù)的混合加密系統(tǒng)您访。
- 變更密碼規(guī)范協(xié)議(Change Cipher Spec Protocol)
是一個非常簡單的“通知”。用于告訴對方剪决,后續(xù)的數(shù)據(jù)都將使用加密保護灵汪。那么反過來檀训,在它之前,數(shù)據(jù)都是明文的享言。為了保障 SSL 傳輸過程的安全峻凫,客戶端和服務器雙方應該每間隔一段時間改變加密規(guī)范。在客戶端和服務器完成握手協(xié)議之后览露,它需要向對方發(fā)送相關消息荧琼,通知對方隨后的數(shù)據(jù)將使用已協(xié)商的加密規(guī)范進行保護。
- 警報協(xié)議(Alert Protocol)
職責是向對方發(fā)出警報信息差牛,類似于 HTTP 協(xié)議里的狀態(tài)碼命锄。比如 protocol_version 就是不支持舊版本,bad_certificate 就是證書有問題偏化,收到警報后另一方可以選擇繼續(xù)脐恩,也可以立即終止連接。警報協(xié)議(Alert Protocol)的職責是向對方發(fā)出警報信息侦讨,類似于 HTTP 協(xié)議里的狀態(tài)碼驶冒。比如 protocol_version 就是不支持舊版本,bad_certificate 就是證書有問題韵卤,收到警報后另一方可以選擇繼續(xù)骗污,也可以立即終止連接。
記錄協(xié)議 (Record Protocol)
建立在可靠的傳輸協(xié)議(如 TCP)之上沈条,為高層協(xié)議提供數(shù)據(jù)封裝身堡、壓縮及加密等基本功能的支持。保證連接的機密性和完整性拍鲤。所有的其他子協(xié)議都需要通過記錄協(xié)議發(fā)出。但多個記錄數(shù)據(jù)可以在一個 TCP 包里一次性發(fā)出汞扎,也并不需要像 TCP 那樣返回 ACK季稳。
有關 SSL 協(xié)議體系結構的更詳細介紹你可以參考這篇文章。
SSL/TLS 在網(wǎng)絡模型中的位置
你是否有想過澈魄?在網(wǎng)絡通信模型中景鼠, TLS 協(xié)議是處在什么位置呢?下面我們通過一張圖來簡單了解下:
SSL/TLS 在網(wǎng)絡模型中屬于應用層協(xié)議(實際在 OSI 的會話層)痹扇,接管應用層的數(shù)據(jù)加解密铛漓,并通過網(wǎng)絡層進行收發(fā)。
TLS 握手過程
下圖簡要描述了 TLS 的握手過程鲫构,其中每個“框”都是一個記錄浓恶,多個記錄組成一個 TCP 包發(fā)送。所以结笨,最多要經(jīng)過 2 RTT(4 個消息)才可以完成握手包晰,然后就可以在安全的通信環(huán)境里發(fā)送 HTTP 報文湿镀,實現(xiàn) HTTPS 協(xié)議。
TLS 握手總是以 ClientHello 消息開始伐憾,就跟 TCP 握手總是以 SYN 包開始一樣勉痴。
上面是相對簡要的握手過程,實際上關于 TLS 握手過程可以劃分為兩種方式:使用 RSA 做密鑰交換和 ECDHE 做密鑰交換树肃。下面我們就詳細地介紹下它們的握手過程蒸矛。
ECDHE 握手
在 TCP 成功建立連接之后,客戶端首先發(fā)送一個 “Client Hello” 消息胸嘴,也就是跟服務器“打招呼”雏掠。
內(nèi)容包括:客戶端的版本號、支持的密碼套件筛谚,還有一個隨機數(shù)(Client Random)磁玉,用于后續(xù)生成會話密鑰抽莱。
Handleshake Protocol: Client Hello
Version: TLS 1.2(0x0303)
Random:1cbf803321fd26234ds78sleds...
Cipher Suites(17 suites)
Cipher Suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
...
可以看到 Client Hello 消息攜帶的相關信息绊起,關鍵的隨機數(shù)需要保留著。
作為“禮尚往來”援雇,服務器收到 “Client Hello” 后吮铭,會返回一個 “Server Hello” 消息时迫。把 TLS 版本對一下,也會返回一個隨機數(shù)(Server Random)谓晌,然后從客戶端的列表里選一個作為本次通信使用的密碼套件掠拳,如下選擇了 “TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384”。
Handshake Protocol: Server Hello
Version: TLS 1.2(0x0303)
Random: 0e6320f21bae50842e96…
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
這個意思是:把版本好對上了纸肉,服務端在客戶端支持的密碼套件中選擇了一個合適的:橢圓曲線 + RSA溺欧、AES、SHA384柏肪。服務端也返回一個隨機數(shù)姐刁,需要客戶端保留著。
然后烦味,服務端為了證明自己的身份聂使,就把證書也發(fā)給客戶端(Server Certificate 消息)。
接下來的關鍵操作谬俄,因為服務器選擇了 ECDHE 算法柏靶,所以它會在證書發(fā)送后發(fā)送 “Server Key Exchange” 消息,里面是橢圓曲線的公鑰(Server Params)溃论,用來實現(xiàn)秘鑰交換算法屎蜓,再加上自己的私鑰簽名認證。
Handshake Protocol: Server Key Exchange
EC Diffie-Hellman Server Params
Curve Type: named_cure (0x03)
Named Curve: x25519 (0x001d)
Pubkey: 3b39deaf00217894e...
Signature Algorithm: rea_pkcs1_sha512 (0x0601)
Signature: 37141adac38ea4...
這一步相當于:服務端又給了一個算法參數(shù)钥勋,和剛才的隨機數(shù)一樣需要客戶端保留梆靖,為了防止別人冒充控汉,服務端用私鑰進行簽名。
之后的 “Server Hello Done” 消息返吻,服務端的“打招呼”完畢姑子。
此時第一個 RTT 就結束了(2 個 TCP 數(shù)據(jù)包),結果是客戶端和服務器通過明文共享了三個信息:Client Random测僵、Server Random 和 Server Params街佑。
客戶端也拿到了服務器的證書,那這個證書里的公鑰是否真實有效呢捍靠?回想下我們在上期《公鑰信任問題 — 數(shù)字證書與 CA》介紹的證書驗證過程沐旨,確認證書的真實性,再用證書公鑰驗證簽名榨婆,就確認了服務器的身份磁携。
然后,客戶端按照密碼套件的要求良风,也生成一個橢圓曲線的公鑰(Client Params)谊迄,用 “Client Key Exchange” 消息發(fā)給服務器。
Handshake Protocol: Client Key Exchange
EC Diffie-Hellman Client Params
Pubkey: 8c674d0e08dc27b5eaa…
現(xiàn)在客戶端和服務器都拿到了密鑰交換算法的兩個參數(shù)(Client Params烟央、Server Params)统诺,就用 ECDHE 算法生成一個 “Pre-Master(預主密鑰,其實也是個隨機數(shù))”疑俭。
具體的計算過程和原理非常復雜粮呢,該計算能夠保證即使黑客截獲了之前的參數(shù),也是絕對算不出這個隨機數(shù)的钞艇。具體你可參考這篇介紹啄寡。
現(xiàn)在客戶端和服務器有了三個隨機數(shù):Client Random、Server Random哩照、Pre-Master(預主密鑰)挺物。然后通過它們生成加密會話的主密鑰 “Master-Secret”。由于黑客拿不到 “Pre-Master”葡秒,所以也就得不到主密鑰。
TLS 的設計考慮的非常全面嵌溢,為了保證真正的“完全隨機和不可預測”眯牧,他們不信任客戶端或服務器的偽隨機數(shù)的可靠性,所以采用三個不可靠的隨機數(shù)混合起來赖草,那么“隨機”的程度就非常高了学少,足夠讓黑客難以猜測。
生成的主密鑰為 48 字節(jié)秧骑,但它還不是最終用于通信的會話密鑰版确,還會再用主密鑰派生出會話密鑰扣囊。到這一步 TLS 的握手就要結束了∪蘖疲客戶端發(fā)送一個 “Change Cipher Spec”侵歇,然后再發(fā)一個 “Finished” 消息,把之前所有發(fā)送的數(shù)據(jù)做個摘要吓蘑,再加密一下惕虑,讓服務器做個驗證。
服務器也是同樣的操作磨镶,發(fā)送 “Change Cipher” 和 “Finished” 消息溃蔫,雙方驗證加密解密 OK,握手正式結束琳猫,后面就開始收發(fā)被加密的 HTTP(Application Data)請求和響應了伟叛。
RSA 握手過程
如今主流的 TLS 握手就是 ECDHE,整個過程可以說是夠復雜的脐嫂。不過整個握手過程好像和其他的地方看到的不一樣呢统刮?這與傳統(tǒng)的握手有 2 點不同:
使用 ECDHE 實現(xiàn)秘鑰交換,而不是 RSA雹锣,所以會在服務端發(fā)出“Server Key Exchange” 消息网沾。
因為使用了 ECDHE,客戶端可以不用等到服務器發(fā)回 “Finished” 確認握手完畢蕊爵,就立即發(fā)出 HTTP 報文了辉哥,節(jié)省了一個 RTT 時間。這個叫做 “TLS False Start”攒射,意思就是“搶跑”醋旦,和 “TCP Fast Open” 有點像,都是不等連接完全建立就提前發(fā)送應用數(shù)據(jù)來提高傳輸效率会放。
下面我們看下傳統(tǒng)的 TLS 握手過程:
大體流程沒有變饲齐,只是 “Pre-Master”(預主密鑰) 不再需要用算法生成,而是客戶端直接生成隨機數(shù)咧最,然后用服務器的公鑰捂人,通過 “Client Key Exchange” 消息發(fā)給服務器。服務器再用私鑰解密矢沿,這樣雙方也實現(xiàn)了共享三個隨機數(shù)滥搭,就可以生成主密鑰。
說道這里捣鲸,TLS 的握手基本上就介紹完了瑟匆。私鑰可以說是整個 TLS/SSL 協(xié)議中最重要的東西了,結合上面介紹的握手過程栽惶,我們再總結下兩種握手過程中私鑰所起到的作用愁溜。
ECDHE 握手時的私鑰用途
對于 ECDHE 來說疾嗅,客戶端和服務端雙方交換的是橢圓曲線參數(shù),私鑰只是用來簽名冕象,這是為了保證消息是持有私鑰者發(fā)送的代承,而非冒充的。雙方交換完參數(shù)之后生成預主密鑰交惯,再生成主密鑰和會話密鑰(這里就和 RSA 后面的流程一樣了)次泽。
RSA 握手時的私鑰用途
對于 RSA 來說,客戶端生成預主密鑰席爽,然后用公鑰加密再發(fā)送給服務器意荤,服務器得到預主密鑰,然后由預主密鑰生成主密鑰只锻,再由主密鑰生成會話密鑰玖像,最后用會話密鑰來通信。
可以看出 RSA 和 ECDHE 密鑰交換算法的私鑰用途是不一樣的齐饮,RSA 密鑰交換時私鑰用來解密捐寥,ECDHE 則是用來簽名。
SSL/TLS 中預主密鑰祖驱,主密鑰和會話密鑰
主密鑰是有預主密鑰握恳、客戶端隨機數(shù)和服務端隨機數(shù)通過 PRF 函數(shù)生成的;會話密鑰是由主密鑰捺僻、客戶端隨機數(shù)和服務器隨機數(shù)聽過 PRF 函數(shù)生成的乡洼,會話密鑰里面包含對稱加密密鑰、消息認證和 CBC 模式的初始向量匕坯,但對于非 CBC 模式的加密算法來說束昵,就沒有用到這個初始向量。
session 緩存和 session ticket 里面保存的主密鑰葛峻,而不是會話密鑰锹雏,這是為了保證每次會話都是獨立的,這樣才能安全术奖。即使一個主密鑰泄露了也不影響其他會話礁遵。關于該部分將在后面的優(yōu)化部分再展開介紹。
雙向認證
大家平時在登錄網(wǎng)上銀行時采记,有時要使用 U 頓給用戶頒發(fā)客戶端證書佣耐。其實那就是雙向認證,即服務端驗證客戶端身份挺庞。
但是在生活中的絕大多數(shù)場景下晰赞,我們只是“單向認證” 的握手過程稼病,只認證了服務器的身份选侨,而沒有認證客戶端的身份掖鱼。這是因為通常單向認證通過后已經(jīng)建立了安全通信,再配合賬號密碼等簡單的手段就能夠確認客戶端的真實身份援制。
雙向認證的流程也沒有發(fā)生太大的變化戏挡,只是在 “Server Hello Done” 之后,“Client Key Exchange” 之前晨仑,客戶端要發(fā)送 “Client Certificate” 消息褐墅,服務器收到后也把證書鏈走一遍,驗證客戶端的身份洪己。
總結
今天我們主要介紹了 HTTPS/TLS 的握手妥凳,整個過程還是比較復雜的。不過為了方便記憶我們可以簡單總結為如下幾條:
HTTPS 協(xié)議在握手之前答捕,需要先進行 TCP 握手逝钥,然后執(zhí)行 TLS 握手,才能建立安全連接拱镐;
TLS 握手的目的是安全地交換對稱密鑰(會話密鑰)艘款,這個過程需要三個隨機數(shù),第三個隨機數(shù) “Pre-Master” 必須加密傳輸沃琅,絕對不能讓黑客破解哗咆;
“Hello” 消息交換隨機數(shù),“Key Exchange” 消息交換 “Pre-Master”益眉;
“Change Cipher Spec” 消息之前傳輸?shù)亩际敲魑纳渭恚蠖际峭ㄟ^對稱密鑰加密的密文。
網(wǎng)絡安全涉及了方方面面太多的知識呜叫,尤其是網(wǎng)絡的基礎知識對我們來說還是非常重要的空繁,關于這部分大家又有什么要分享的?歡迎你的分享留言或指正朱庆。
網(wǎng)絡安全系列專題
擴展閱讀