假如讓你來(lái)設(shè)計(jì) SSL/TLS 協(xié)議
前言
說(shuō)起網(wǎng)絡(luò)通信協(xié)議,相信大家對(duì) TCP 和 HTTP 都很熟悉,它們可以說(shuō)是當(dāng)今互聯(lián)網(wǎng)通信的基石。但是,在網(wǎng)絡(luò)安全方面,它們卻是有著很大安全風(fēng)險(xiǎn):
- 竊聽(tīng)風(fēng)險(xiǎn)。第三方攻擊者可以隨意竊聽(tīng)通信內(nèi)容,比如獲取支付賬號(hào)密碼。
- 冒充風(fēng)險(xiǎn)。第三方攻擊者可以冒充他人身份與你通信,比如冒充銀行網(wǎng)站以竊取銀行賬號(hào)密碼。
- 篡改風(fēng)險(xiǎn)。第三方攻擊者可以隨意修改通信內(nèi)容,比如在響應(yīng)上加入釣魚(yú)網(wǎng)址。
為此,SSL/TLS 協(xié)議應(yīng)運(yùn)而生。SSL/TLS 是建立在傳輸層之上、應(yīng)用層之下的安全通信協(xié)議,它主要的設(shè)計(jì)意圖就是消除上述幾種安全風(fēng)險(xiǎn),保證網(wǎng)絡(luò)通信安全。我們熟知的 HTTPS 就是 HTTP + SSL/TLS 構(gòu)建的,可以說(shuō) SSL/TLS 是當(dāng)今互聯(lián)網(wǎng)安全通信的基石。
那么,現(xiàn)在假如讓你來(lái)設(shè)計(jì) SSL/TLS 協(xié)議,你會(huì)怎么設(shè)計(jì)呢?
本文將從設(shè)計(jì)者的視角介紹如何一步步設(shè)計(jì)出一個(gè)簡(jiǎn)易版的 SSL/TLS 的過(guò)程,在文章的最后,再簡(jiǎn)單介紹 TLS 1.2 版本的工作機(jī)制,以此幫助大家對(duì) SSL/TLS 協(xié)議的基本原理有一個(gè)更深入的理解。
基于對(duì)稱(chēng)加密算法的數(shù)據(jù)加密
竊聽(tīng)風(fēng)險(xiǎn)主要是因?yàn)橥ㄐ烹p方在網(wǎng)絡(luò)上明文傳輸數(shù)據(jù),導(dǎo)致攻擊者可以通過(guò)簡(jiǎn)單網(wǎng)絡(luò)抓包就能獲取到通信的內(nèi)容。
要解決竊聽(tīng)風(fēng)險(xiǎn),就最好的方法就是對(duì)數(shù)據(jù)進(jìn)行加密。也即客戶(hù)端在把數(shù)據(jù)發(fā)送出去之前,先對(duì)數(shù)據(jù)進(jìn)行加密;服務(wù)端收到密文之后,再進(jìn)行解密還原數(shù)據(jù)。這樣就能避免在網(wǎng)絡(luò)上傳播明文,從而可以防止第三方攻擊者的竊聽(tīng)。
提到加密算法,很多人首先會(huì)想到對(duì)稱(chēng)加密算法,它以簡(jiǎn)單和高效著稱(chēng)。對(duì)稱(chēng)加密指的是加密和解密都使用同一份密鑰,常見(jiàn)的算法有 DES、AES 等。
現(xiàn)在,我們?cè)囍褂脤?duì)稱(chēng)加密算法來(lái)實(shí)現(xiàn)安全通信:
使用對(duì)稱(chēng)密鑰加密的前提是,通信雙方都必須用同一份密鑰來(lái)對(duì)數(shù)據(jù)進(jìn)行加密。主要有線(xiàn)下和線(xiàn)上密鑰交換兩種方案可以達(dá)到該目的:
- 線(xiàn)下密鑰交換,也即通信雙方線(xiàn)下約定好當(dāng)面交換密鑰(比如通過(guò)U盤(pán)作為媒介)。該方案可以保證密鑰交換的安全性,但是很難推廣使用。因?yàn)樵诮^大多數(shù)場(chǎng)景中,客戶(hù)端和服務(wù)端都不可能碰面。
- 線(xiàn)上密鑰交換,也即通過(guò)網(wǎng)絡(luò)來(lái)傳輸密鑰。但在網(wǎng)絡(luò)明文傳輸密鑰同樣也會(huì)被攻擊者攔截,這樣的加密也沒(méi)有意義了。
因此,單純的對(duì)稱(chēng)加密并不能滿(mǎn)足通信安全的要求,我們還要繼續(xù)優(yōu)化......
基于非對(duì)稱(chēng)加密算法的數(shù)據(jù)加密
非對(duì)稱(chēng)加密算法指的是加密和解密使用不同的密鑰,這兩個(gè)不同的密鑰組成一個(gè)密鑰對(duì),也即公鑰和私鑰。公鑰是公開(kāi)的密鑰,所有人都能獲取到;私鑰則是保密的。當(dāng)我們使用公鑰對(duì)數(shù)據(jù)進(jìn)行加密后,只有對(duì)應(yīng)的私鑰才能完成解密。常見(jiàn)的非對(duì)稱(chēng)加密算法有 RSA、ECC 等。
現(xiàn)在,我們?cè)囍褂梅菍?duì)稱(chēng)加密算法來(lái)實(shí)現(xiàn)安全通信:
通過(guò)非對(duì)稱(chēng)加密算法,我們既能實(shí)現(xiàn)對(duì)數(shù)據(jù)的加密,又能解決密鑰交換的問(wèn)題,從而消除了竊聽(tīng)風(fēng)險(xiǎn)。但是,非對(duì)稱(chēng)加密算法最大的缺點(diǎn),就是加解密速度很慢,相比于對(duì)稱(chēng)加密算法要慢1000多倍。因此,非對(duì)稱(chēng)加密算法通常只適用于對(duì)少量數(shù)據(jù)的加密。
到目前為止,單純地使用對(duì)稱(chēng)加密算法或非對(duì)稱(chēng)加密算法都無(wú)法滿(mǎn)足要求,還需要繼續(xù)優(yōu)化......
基于對(duì)稱(chēng)加密+非對(duì)稱(chēng)加密算法的數(shù)據(jù)加密
既然對(duì)稱(chēng)加密算法加解密速度快,但存在密鑰交換的問(wèn)題;而非對(duì)稱(chēng)加密算法可以解決密鑰交換問(wèn)題,但加解密速度慢。那么我們可以把兩種算法結(jié)合起來(lái),也即通過(guò)對(duì)稱(chēng)加密算法進(jìn)行數(shù)據(jù)加密,在交換對(duì)稱(chēng)密鑰時(shí),使用非對(duì)稱(chēng)加密算法來(lái)加密對(duì)稱(chēng)密鑰,確保密鑰在網(wǎng)絡(luò)傳輸過(guò)程中不會(huì)被攻擊者竊聽(tīng)。
現(xiàn)在,我們?cè)囍褂脤?duì)稱(chēng)加密+非對(duì)稱(chēng)加密算法來(lái)實(shí)現(xiàn)安全通信:
使用對(duì)稱(chēng)加密+非對(duì)稱(chēng)加密算法的方案,我們消除了竊聽(tīng)風(fēng)險(xiǎn),也不會(huì)存在加解密性能問(wèn)題,但是還是無(wú)法消除冒充風(fēng)險(xiǎn)。
考慮如下場(chǎng)景:
- 攻擊者把服務(wù)端的公鑰攔截,并保存下來(lái)。
- 攻擊者偽造成服務(wù)端,把自己的公鑰發(fā)送給客戶(hù)端。
- 攻擊者攔截使用非法公鑰加密后的對(duì)稱(chēng)密鑰,解密后得到對(duì)稱(chēng)密鑰明文,并保存下來(lái)。
- 攻擊者使用服務(wù)端公鑰重新加密對(duì)稱(chēng)密鑰,偽造成客戶(hù)端發(fā)送給服務(wù)端。
這番操作后,攻擊者就能在客戶(hù)端和服務(wù)端都不知情的情況下,得到了對(duì)稱(chēng)密鑰。在這種場(chǎng)景下,攻擊者從被動(dòng)攻擊的竊聽(tīng),轉(zhuǎn)為主動(dòng)攻擊的冒充,讓客戶(hù)端和服務(wù)端都誤以為一直在跟對(duì)方通信。
因此,我們需要找到一種方法,讓客戶(hù)端能夠確保自己收到的公鑰,一定是真實(shí)的服務(wù)端發(fā)送過(guò)來(lái)的,也即能夠認(rèn)證“服務(wù)端”的真實(shí)身份......
基于CA證書(shū)的身份認(rèn)證
數(shù)字證書(shū)概述
引用百度百科的定義:
數(shù)字證書(shū)是指在互聯(lián)網(wǎng)通訊中標(biāo)志通訊各方身份信息的一個(gè)數(shù)字認(rèn)證,人們可以在網(wǎng)上用它來(lái)識(shí)別對(duì)方的身份。
數(shù)字證書(shū)(Digital Certificate)就好比現(xiàn)實(shí)世界中的身份證,用于標(biāo)識(shí)一個(gè)網(wǎng)絡(luò)用戶(hù)(人、公司、服務(wù)器等)的合法身份。就像身份證必須由公安局來(lái)頒發(fā),可信的數(shù)字證書(shū)也必須由一個(gè)權(quán)威機(jī)構(gòu)來(lái)頒發(fā),該機(jī)構(gòu)就是證書(shū)授權(quán)中心(Certificate Authority,CA),CA 頒發(fā)的數(shù)字證書(shū)我們通常稱(chēng)作 CA 證書(shū)。
一個(gè) CA 證書(shū)主要包含申請(qǐng)者的公鑰、申請(qǐng)者的信息、簽發(fā)機(jī)構(gòu) CA 的信息、有效時(shí)間、證書(shū)序列號(hào)等明文信息,同時(shí)也包含一個(gè) CA 的數(shù)字簽名,正是該簽名的存在才證明了該證書(shū)的有效性。
數(shù)字簽名建立在非對(duì)稱(chēng)加密算法的基礎(chǔ)上,CA 在頒發(fā)證書(shū)時(shí),會(huì)先將證書(shū)的明文信息用指定的算法(比如 SHA256 算法)計(jì)算出一個(gè)數(shù)字摘要,再使用 CA 的私鑰對(duì)摘要進(jìn)行加密,形成簽名。
而證書(shū)的驗(yàn)證主要包含如下兩部分:
- 檢查證書(shū)的明文信息是否有效,比如證書(shū)是否過(guò)期、域名是否一致等。
- 用 CA 公布的公鑰對(duì)證書(shū)簽名進(jìn)行解密,得到數(shù)字摘要1。再使用同樣的算法對(duì)證書(shū)明文信息計(jì)算得出數(shù)字摘要2。對(duì)比數(shù)字摘要1和數(shù)字摘要2是否相等。
頒發(fā)證書(shū)的機(jī)構(gòu)并非只有一個(gè),比如機(jī)構(gòu) A 可以用 CA 頒發(fā)的根證書(shū)去給機(jī)構(gòu) B 頒發(fā)二級(jí)證書(shū);機(jī)構(gòu) B 又可以用二級(jí)證書(shū)去給機(jī)構(gòu) C 頒發(fā)三級(jí)證書(shū),以此類(lèi)推,也即所謂的證書(shū)鏈。
使用CA證書(shū)認(rèn)證通信雙方的身份
現(xiàn)在,我們加入 CA 證書(shū)來(lái)認(rèn)證通信雙方的身份:
引入 CA 證書(shū)之后,服務(wù)端的公鑰就放在它提供的證書(shū)之中,當(dāng)客戶(hù)端驗(yàn)證服務(wù)端證書(shū)通過(guò)后,也就說(shuō)明其中的公鑰確實(shí)是來(lái)自服務(wù)端的合法公鑰。這樣,后續(xù)的通信流程就可以正常地進(jìn)行了。
然而,如果對(duì)稱(chēng)密鑰一直不變的話(huà),攻擊者還是很有可能暴力破解出對(duì)稱(chēng)密鑰。因此,我們還需要最好能夠?qū)崿F(xiàn)每次連接的對(duì)稱(chēng)密鑰都是不同的......
使用隨機(jī)數(shù)來(lái)生成對(duì)稱(chēng)密鑰
為了使每次連接的對(duì)稱(chēng)密鑰都不同,我們可以引入隨機(jī)數(shù)來(lái)生成對(duì)稱(chēng)密鑰,保證它的隨機(jī)性。但是,考慮到當(dāng)前計(jì)算機(jī)生成的隨機(jī)數(shù)都是偽隨機(jī)數(shù),為了進(jìn)一步提升隨機(jī)性,我們可以通過(guò)生成多個(gè)隨機(jī)數(shù)來(lái)達(dá)到此目的。
我們可以這么設(shè)計(jì):
- 客戶(hù)端和服務(wù)端先各生成一個(gè)隨機(jī)數(shù)(隨機(jī)數(shù)1和隨機(jī)數(shù)2),在 ClientHello 和 ServerHello 報(bào)文中完成交換。
- 客戶(hù)端在驗(yàn)證完服務(wù)端的身份后,再生成隨機(jī)數(shù)3,通過(guò)服務(wù)端的公鑰加密發(fā)給服務(wù)端。(此時(shí),通信雙方都擁有了 3 個(gè)一樣隨機(jī)數(shù))。
- 客戶(hù)端和服務(wù)端再根據(jù)這 3 個(gè)隨機(jī)數(shù),生成最終的對(duì)稱(chēng)密鑰。
這樣通過(guò) 3 個(gè)隨機(jī)數(shù)來(lái)生成的密鑰,就能較好地保證了密鑰的隨機(jī)性,降低被攻擊者破解的可能。
雖然隨機(jī)數(shù)1和隨機(jī)數(shù)2是明文傳輸,但隨機(jī)數(shù)3是密傳輸,也就能夠保證攻擊者很難破解到密鑰。
到目前為止,我們已經(jīng)通過(guò)多種手段成功阻止了攻擊者竊聽(tīng)客戶(hù)端和服務(wù)端之間的通信內(nèi)容。但是,如果攻擊者并不以竊聽(tīng)通信內(nèi)容為目的,而是單純地想搞破壞。比如,攻擊者攔截了 ClientHello報(bào)文,把其中的隨機(jī)數(shù)1改成了隨機(jī)數(shù)4,這樣就會(huì)導(dǎo)致客戶(hù)端和服務(wù)端生成的密鑰不一致。在此場(chǎng)景下,雖然連接已經(jīng)建立起來(lái)了,但是客戶(hù)端和服務(wù)端還是無(wú)法正常地通信:
為此,我們需要一種機(jī)制,校驗(yàn)連接建立階段(握手階段)所有消息的正確性,防止建立錯(cuò)誤的連接......
校驗(yàn)握手消息的正確性
我們可以利用數(shù)字摘要來(lái)校驗(yàn)所有握手消息的正確性,也即,在握手階段的最后,通信雙方都通過(guò) Hash 算法(比如 SHA256)對(duì)自己收到的和發(fā)送的所有消息計(jì)算出數(shù)字摘要,然后使用前面協(xié)商好的對(duì)稱(chēng)密鑰對(duì)該數(shù)字摘要進(jìn)行加密,發(fā)送給對(duì)方。
當(dāng)收到對(duì)方發(fā)過(guò)來(lái)的數(shù)字摘要密文后,先用對(duì)稱(chēng)密鑰對(duì)其進(jìn)行解密,如果解密成功,說(shuō)明密鑰生成沒(méi)問(wèn)題;接著對(duì)比雙方的數(shù)字摘要是否一致,如果一致,說(shuō)明握手階段的消息沒(méi)有被篡改過(guò),也即可以建立起正確的連接了。
到現(xiàn)在,我們基本上已經(jīng)消除了竊聽(tīng)風(fēng)險(xiǎn)(通過(guò)數(shù)據(jù)加密)、冒充風(fēng)險(xiǎn)(通過(guò)證書(shū)認(rèn)證)和篡改風(fēng)險(xiǎn)(通過(guò)數(shù)字摘要)。但是,為了建立起安全通信通道,我們需要經(jīng)歷多次消息交互、加解密、身份認(rèn)證等步驟,對(duì)性能有一定的損耗。
因?yàn)榻?jīng)歷過(guò)一次握手之后,密鑰已經(jīng)協(xié)商好,并且雙方都保存了下來(lái)。下次連接建立時(shí),完全可以沿用上次握手協(xié)商好的密鑰,從而避免了重新協(xié)商密鑰,提升了性能。我們需要一種重用會(huì)話(huà)的機(jī)制來(lái)提升協(xié)議的性能......
重用會(huì)話(huà)來(lái)提升性能
為了達(dá)到沿用上次協(xié)商好的密鑰的目的,我們?yōu)槊看芜B接都分配一個(gè)會(huì)話(huà) ID。
- 在初次創(chuàng)建連接時(shí),由服務(wù)端生成,并通過(guò) ServerHello 返回給客戶(hù)端。
- 在下一次創(chuàng)建連接時(shí),客戶(hù)端通過(guò) ClientHello 把該會(huì)話(huà) ID 發(fā)給服務(wù)端,表示希望重用該會(huì)話(huà)。
- 服務(wù)端在收到該會(huì)話(huà) ID 后,就可以發(fā)送 Finished 消息,表示同意了會(huì)話(huà)重用,也即可以沿用上次會(huì)話(huà)協(xié)商好的密鑰進(jìn)行安全通信了。
到這里,我們已經(jīng)完成了一個(gè)簡(jiǎn)易版的 SSL/TLS 協(xié)議的設(shè)計(jì),真實(shí)的 SSL/TLS 協(xié)議當(dāng)然沒(méi)這么簡(jiǎn)單,但是里面的核心思想和基本原理都是類(lèi)似的。只是 SSL/TLS 為了更好的安全性、擴(kuò)展性和易用性等增加了一些機(jī)制,比如支持多種加密算法、使用 MAC 替代普通的數(shù)字摘要完成完整性校驗(yàn)。
下面,我們將簡(jiǎn)單介紹真實(shí)的 SSL/TLS 協(xié)議的工作機(jī)制。
SSL/TLS協(xié)議機(jī)制概述
SSL 協(xié)議(Secure Sockets Layer)是 TLS(Transport Layer Security)協(xié)議的前身,它們的版本演進(jìn)如下,當(dāng)前最新的版本為 TLS 1.3 版本。本節(jié),我們將以當(dāng)前使用最廣泛的 TLS 1.2 版本作為分析對(duì)象,介紹 SSL/TLS 的基本工作機(jī)制。
SSL 1.0版本 -> SSL 2.0版本 -> SSL 3.0版本 -> TLS 1.0版本 -> TLS 1.1版本 -> TLS 1.2版本 -> TLS 1.3版本。
SSL/TLS協(xié)議總覽
SSL/TLS 協(xié)議位于網(wǎng)絡(luò)協(xié)議棧中傳輸層和應(yīng)用層之間,它內(nèi)部又可以分為 2 層,總共 5 種子協(xié)議:
Record協(xié)議
最底層的 Record 協(xié)議負(fù)責(zé)對(duì)上層子協(xié)議的封裝,提供安全通信的能力:
- 私密連接。使用對(duì)稱(chēng)加密算法(比如 AES、RC4 等)來(lái)加密數(shù)據(jù),而且在每次連接中,通信雙方協(xié)商出來(lái)的加密密鑰都是不同的,以此達(dá)到更好的安全性。另外,Record 協(xié)議也可以提供不加密的封裝,比如在握手階段的 Hello 報(bào)文。
- 可靠連接。使用 MAC(Message Authentication Code,消息驗(yàn)證碼,TLS 目前使用的 HMAC 也屬于 MAC 的一種)為數(shù)據(jù)提供完整性校驗(yàn)。同樣,在握手階段也可以不使用該功能。
Handshake 協(xié)議
上層的 Handshake 協(xié)議用在握手階段,為通信雙方提供身份認(rèn)證、加密算法和密鑰協(xié)商的能力:
- 身份認(rèn)證?;?CA 證書(shū)完成對(duì)端的身份認(rèn)證,其中用到了非對(duì)稱(chēng)加密技術(shù)(比如 RSA、DES 等)。該功能是可選的,但通常的做法是至少進(jìn)行單向認(rèn)證。
- 安全參數(shù)的協(xié)商。完成用于安全參數(shù)的協(xié)商(比如加密算法、哈希算法、密鑰等),并且能夠保證在協(xié)商過(guò)程中,攻擊者無(wú)法獲取密鑰。
- 可靠協(xié)商。確保在安全參數(shù)等協(xié)商過(guò)程中,攻擊者無(wú)法對(duì)報(bào)文實(shí)施篡改。
Handshake 協(xié)議包含了如下幾種報(bào)文類(lèi)型:ClientHello、SeverHello、Certificate、ServerKeyExchange、CertificateRequest、ServerHelloDone、ClientKeyExchange、CertificateVerify、ChangeCipherSpec、Finished。
Change Cipher Spec協(xié)議
Change Cipher Spec 協(xié)議也用在握手階段,當(dāng)通信的一方發(fā)出Change Cipher Spec 報(bào)文時(shí),就表示密鑰已經(jīng)協(xié)商好,從下一條消息開(kāi)始,使用該密鑰來(lái)進(jìn)行加密傳輸。
Alert 協(xié)議
Alert 協(xié)議只有在連接異常時(shí)才會(huì)用上,當(dāng)前協(xié)議定義的 Alert 消息類(lèi)型如下:
close_notify: 表示發(fā)送方不會(huì)再發(fā)送任何消息,用于正常關(guān)閉連接,類(lèi)似于TCP中的FIN報(bào)文
unexpected_message: 收到不在預(yù)期之內(nèi)的消息
bad_record_mac: 收到的消息中MAC不正確,表示消息已經(jīng)被篡改過(guò)
decryption_failed_RESERVED: 解密失敗,用于TLS的早期版本
record_overflow: 消息長(zhǎng)度溢出,密文長(zhǎng)度不超過(guò)2^14+2048字節(jié);壓縮后的明文不超過(guò)2^14+1024字節(jié)
decompression_failure: 使用壓縮功能時(shí),解壓失敗
handshake_failure: 握手階段無(wú)法協(xié)商出正確的安全參數(shù)
no_certificate_RESERVED: 為了兼容SSL 3.0版本,TLS不再使用
bad_certificate: 證書(shū)簽名認(rèn)證失敗
unsupported_certificate: 收到不支持的證書(shū)類(lèi)型
certificate_revoked: 收到被廢棄的證書(shū)
certificate_expired: 收到過(guò)期的證書(shū)
certificate_unknown: 除上述4種情況外,其他證書(shū)異常場(chǎng)景
illegal_parameter: 握手階段報(bào)文的參數(shù)非法,比如范圍溢出等
unknown_ca: 不可信任的CA頒發(fā)的證書(shū)
access_denied: 證書(shū)校驗(yàn)通過(guò),但發(fā)送方卻拒絕繼續(xù)握手
decode_error: 消息解碼失敗
decrypt_error: 握手階段安全相關(guān)的步驟失敗,比如簽名校驗(yàn)失敗、Finished消息校驗(yàn)失敗等
export_restriction_RESERVED: 早期的TLS版本使用
protocol_version: 協(xié)議版本不支持
insufficient_security: 服務(wù)端要求的安全算法,客戶(hù)端無(wú)法滿(mǎn)足
internal_error: 協(xié)議內(nèi)部錯(cuò)誤
user_canceled: 用戶(hù)非正常主動(dòng)關(guān)閉連接
no_renegotiation: 拒絕重新握手
unsupported_extension: 不支持的擴(kuò)展
Application Data 協(xié)議
Application Data 協(xié)議用在通信階段,封裝了應(yīng)用層的數(shù)據(jù),經(jīng)由 Record 協(xié)議封裝之后,通過(guò) TCP 協(xié)議轉(zhuǎn)發(fā)出去。
SSL/TLS 協(xié)議的握手過(guò)程
第一次握手
客戶(hù)端向服務(wù)端發(fā)送 ClientHello 報(bào)文發(fā)起連接建立,其中攜帶了如下內(nèi)容:
- Version: 客戶(hù)端支持的TLS協(xié)議版本
- Random: 客戶(hù)端生成的隨機(jī)數(shù),隨后用于生成 master secret
- SessionID: 會(huì)話(huà) ID,如果不為空,表示客戶(hù)端想重用該會(huì)話(huà)
- CipherSuites: 客戶(hù)端支持的加密套件列表,在 SessionID 為空時(shí)必須攜帶
- CompressionMethods: 客戶(hù)端支持的壓縮算法列表
- Extensions: 擴(kuò)展內(nèi)容
第二次握手
1.服務(wù)端向客戶(hù)端發(fā)送 ServerHello 報(bào)文,其中攜帶了如下內(nèi)容:
- Version: 選定的 TLS 版本,選擇通信雙方都支持的最高版本
- Random: 服務(wù)端生成的隨機(jī)數(shù),隨后用于生成 master secret
- SessionID: 會(huì)話(huà) ID,如果為空,表示服務(wù)端開(kāi)啟新的會(huì)話(huà),并且不希望被重用;如果與客戶(hù)端帶過(guò)來(lái)的 SessionID 一樣,表示重用該會(huì)話(huà);否則,開(kāi)啟一個(gè)新的會(huì)話(huà),并且在未來(lái)可能會(huì)被重用
- CipherSuite: 選定的加密套件
- CompressionMethod: 選定的壓縮算法
- Extensions: 擴(kuò)展內(nèi)容
2.服務(wù)端向客戶(hù)端發(fā)送 Certificate 報(bào)文,其中攜帶了服務(wù)端的證書(shū),證書(shū)必須是 x.509 標(biāo)準(zhǔn)格式,包含服務(wù)端公鑰、服務(wù)端域名、簽發(fā)方信息、有效期等信息。
可選,客戶(hù)端需要通過(guò)證書(shū)來(lái)認(rèn)證服務(wù)端身份時(shí)發(fā)送。
3.服務(wù)端向客戶(hù)端發(fā)送 Server Key Exchange 報(bào)文,其中攜帶了客戶(hù)端用于生成 premaster secret 的安全參數(shù)。
可選,當(dāng) Certificate 報(bào)文中攜帶的信息無(wú)法支撐客戶(hù)端生成 premaster secret 時(shí)發(fā)送。
4.服務(wù)端向客戶(hù)端發(fā)送 CertificateRequest 報(bào)文,索求客戶(hù)端證書(shū),其中包含了期望的證書(shū)類(lèi)型、簽名算法和CA列表。
可選,開(kāi)啟雙向認(rèn)證時(shí)發(fā)送。
5.服務(wù)端向客戶(hù)端發(fā)送 ServerHelloDone 報(bào)文,表示當(dāng)前服務(wù)端已經(jīng)把所有與密鑰交換相關(guān)的內(nèi)容都發(fā)送完畢。
第三次握手
1.客戶(hù)端向服務(wù)端發(fā)送 Certificate 報(bào)文,其中攜帶了客戶(hù)端證書(shū)。
可選,收到服務(wù)端的 CertificateRequest 報(bào)文時(shí)發(fā)送。
2.客戶(hù)端向服務(wù)端發(fā)送 ClientKeyExchange 報(bào)文,其中包含了使用服務(wù)端公鑰加密后的 premaster secret (隨機(jī)數(shù)),隨后用于生成master secret。
3.客戶(hù)端向服務(wù)端發(fā)送 CertificateVerify 報(bào)文,其中包含了對(duì)通信雙方到目前為止所有握手報(bào)文的數(shù)字簽名,用于證明自己擁有的私鑰與之前發(fā)送的證書(shū)中的公鑰相對(duì)應(yīng)。
可選,給服務(wù)端發(fā)送 Certificate 報(bào)文時(shí)發(fā)送。
4.客戶(hù)端向服務(wù)端發(fā)送 ChangeCipherSpec 報(bào)文,表示從下條消息開(kāi)始進(jìn)行加密傳輸。
5.客戶(hù)端向服務(wù)端發(fā)送 Finished 報(bào)文,加密傳輸,其中包含了所有握手消息的數(shù)字摘要,用于防篡改。
第四次握手
1.服務(wù)端向客戶(hù)端發(fā)送 ChangeCipherSpec 報(bào)文,表示從下條消息開(kāi)始進(jìn)行加密傳輸。
2.服務(wù)端向客戶(hù)端發(fā)送 Finished 報(bào)文,加密傳輸,其中包含了所有握手消息的數(shù)字摘要,用于防篡改。
最后
SSL/TLS 協(xié)議也并非絕對(duì)安全,它也有許多漏洞被黑客們不斷地挖掘出來(lái),當(dāng)然,SSL/TLS 協(xié)議也在不斷地完善。2018 年發(fā)布的 TLS 1.3 版本就在 TLS 1.2 版本的基礎(chǔ)上做了許多增強(qiáng)。比如,在性能上,握手階段從 2-RTT 縮減為 1-RTT,并支持 0-RTT 模式;在安全上,ServerHello 報(bào)文之后就開(kāi)始加密傳輸、一些不安全的加密套件也不再支持(比如靜態(tài) RSA、Diffie-Hellman 等)。
雖然 TLS 1.3 版本機(jī)制上改變了很多,但是基本原理還是一樣的。因此,把 SSL/TLS 協(xié)議原理理解透了,后續(xù)不管版本再怎么演進(jìn),我們都能快速完成協(xié)議機(jī)制的學(xué)習(xí)。
參考
The Transport Layer Security (TLS) Protocol Version 1.2,RFC 5246
The Transport Layer Security (TLS) Protocol Version 1.3,RFC 8446
SSL/TLS 協(xié)議運(yùn)行機(jī)制的概述,阮一峰
Overview of SSL/TLS Encryption, MicroSoft Document
The First Few Milliseconds of an HTTPS Connection,Jeff Moser
為什么 HTTPS 需要 7 次握手以及 9 倍時(shí)延,面向信仰編程
HTTPS權(quán)威指南,楊洋、李振宇等
數(shù)字證書(shū), 百度百科