深入淺出 HTTPS (詳解版)

原文鏈接:https://www.cnblogs.com/huansky/p/13977181.html

前言

1990年互聯(lián)網(wǎng)誕生之初牺弹,就已經(jīng)開始用超文本傳輸協(xié)議 HTTP 傳輸數(shù)據(jù)团甲,這也是為什么現(xiàn)在網(wǎng)頁地址都是以 http 開頭的原因荠察。但是HTTP協(xié)議傳輸數(shù)據(jù)是明文傳輸祷膳,任意的人抓包就能看到傳輸?shù)臄?shù)據(jù),這顯然不安全。1994年,Netscape 公司用加密協(xié)議增加了 HTTP,開始在 HTTP 的基礎上加入 SSL 即安全套接層(Secure Socket Layer)呐萨。稱為 "HTTP over SSL" 或者 "HTTP Secure",也就是我們現(xiàn)在熟知的 HTTPS莽囤。

HTTPS 其實是一個“非常簡單”的協(xié)議垛吗,RFC 文檔很小,只有短短的 7 頁烁登,里面規(guī)定了新的協(xié)議名“https”怯屉,默認端口號 443,至于其他的什么請求 - 應答模式饵沧、報文結(jié)構(gòu)锨络、請求方法、URI狼牺、頭字段羡儿、連接管理等等都完全沿用 HTTP,沒有任何新的東西是钥。

也就是說掠归,除了協(xié)議名“http”和端口號 80 這兩點不同,HTTPS 協(xié)議在語法悄泥、語義上和 HTTP 完全一樣虏冻,優(yōu)缺點也“照單全收”(當然要除去“明文”和“不安全”)。

對于 http 請求還不是很了解的弹囚,可以閱讀以下幾篇文章

  1. HTTP 概述

  2. TCP 三次握手和四次揮手圖解(有限狀態(tài)機)

  3. 從你輸入網(wǎng)址厨相,到看到網(wǎng)頁——詳解中間發(fā)生的過程

  4. 漫談 HTTP 性能優(yōu)化

SSL/TLS

SSL/TLS是位于TCP/IP 7層協(xié)議中的會話層,用于認證用戶和服務器鸥鹉,加解密數(shù)據(jù)以及維護數(shù)據(jù)的完整性蛮穿,確保數(shù)據(jù)在傳輸過程中不會被修改。

SSL 有 v2 和 v3 兩個版本毁渗,而 v1 因為有嚴重的缺陷從未公開過践磅。SSL 發(fā)展到 v3 時已經(jīng)證明了它自身是一個非常好的安全通信協(xié)議,于是互聯(lián)網(wǎng)工程組 IETF 在 1999 年把它改名為 TLS(傳輸層安全灸异,Transport Layer Security)府适,正式標準化幻碱,版本號從 1.0 重新算起,所以 TLS1.0 實際上就是 SSLv3.1细溅。

到今天 TLS 已經(jīng)發(fā)展出了三個版本,分別是 2006 年的 1.1儡嘶、2008 年的 1.2 和去年(2018)的 1.3喇聊,每個新版本都緊跟密碼學的發(fā)展和互聯(lián)網(wǎng)的現(xiàn)狀,持續(xù)強化安全和性能蹦狂,已經(jīng)成為了信息安全領域中的權威標準誓篱。

目前應用的最廣泛的 TLS 是 1.2,而之前的協(xié)議(TLS1.1/1.0凯楔、SSLv3/v2)都已經(jīng)被認為是不安全的窜骄,各大瀏覽器即將在 2020 年左右停止支持,所以接下來的講解都針對的是 TLS1.2摆屯。

TLS 由記錄協(xié)議邻遏、握手協(xié)議、警告協(xié)議虐骑、變更密碼規(guī)范協(xié)議准验、擴展協(xié)議等幾個子協(xié)議組成,綜合使用了對稱加密廷没、非對稱加密糊饱、身份認證等許多密碼學前沿技術。瀏覽器和服務器在使用 TLS 建立連接時需要選擇一組恰當?shù)募用芩惴▉韺崿F(xiàn)安全通信颠黎,這些算法的組合被稱為“密碼套件”(cipher suite另锋,也叫加密套件)。

SSL/TLS分為對稱加密和非對稱加密兩種方式狭归。

對稱加密

對稱加密是指加密和解密都用同一份密鑰夭坪。如下圖所示:

AES 的意思是“高級加密標準”(Advanced Encryption Standard),密鑰長度可以是 128过椎、192 或 256台舱。它是 DES 算法的替代者,安全強度很高潭流,性能也很好竞惋,而且有的硬件還會做特殊優(yōu)化,所以非常流行灰嫉,是應用最廣泛的對稱加密算法拆宛。

ChaCha20 是 Google 設計的另一種加密算法,密鑰長度固定為 256 位讼撒,純軟件運行性能要超過 AES浑厚,曾經(jīng)在移動客戶端上比較流行股耽,但 ARMv8 之后也加入了 AES 硬件優(yōu)化,所以現(xiàn)在不再具有明顯的優(yōu)勢钳幅,但仍然算得上是一個不錯算法物蝙。

非對稱加密

非對稱加密對應于一對密鑰,稱為私鑰和公鑰敢艰,用私鑰加密后需要用公鑰解密诬乞,用公鑰加密后需要用私鑰解密。如下圖所示:

對稱加密看上去好像完美地實現(xiàn)了機密性钠导,但其中有一個很大的問題:如何把密鑰安全地傳遞給對方震嫉,術語叫“密鑰交換”。

因為在對稱加密算法中只要持有密鑰就可以解密牡属。如果你和網(wǎng)站約定的密鑰在傳遞途中被黑客竊取票堵,那他就可以在之后隨意解密收發(fā)的數(shù)據(jù),通信過程也就沒有機密性可言了逮栅。

這個問題該怎么解決呢悴势?

你或許會說:“把密鑰再加密一下發(fā)過去就好了”,但傳輸“加密密鑰的密鑰”又成了新問題措伐。這就像是“雞生蛋瞳浦、蛋生雞”,可以無限遞歸下去废士。只用對稱加密算法叫潦,是絕對無法解決密鑰交換的問題的。

所以官硝,就出現(xiàn)了非對稱加密(也叫公鑰加密算法)矗蕊。

它有兩個密鑰,一個叫“公鑰”(public key)氢架,一個叫“私鑰”(private key)傻咖。兩個密鑰是不同的,“不對稱”岖研,公鑰可以公開給任何人使用卿操,而私鑰必須嚴格保密。

公鑰和私鑰有個特別的“單向”性孙援,雖然都可以用來加密解密害淤,但公鑰加密后只能用私鑰解密,反過來拓售,私鑰加密后也只能用公鑰解密窥摄。

非對稱加密可以解決“密鑰交換”的問題。網(wǎng)站秘密保管私鑰础淤,在網(wǎng)上任意分發(fā)公鑰崭放,你想要登錄網(wǎng)站只要用公鑰加密就行了哨苛,密文只能由私鑰持有者才能解密。而黑客因為沒有私鑰币砂,所以就無法破解密文建峭。

非對稱加密算法的設計要比對稱算法難得多,在 TLS 里只有很少的幾種决摧,比如 DH亿蒸、DSA、RSA蜜徽、ECC 等。

  1. RSA 可能是其中最著名的一個票摇,幾乎可以說是非對稱加密的代名詞拘鞋,它的安全性基于“整數(shù)分解”的數(shù)學難題,使用兩個超大素數(shù)的乘積作為生成密鑰的材料矢门,想要從公鑰推算出私鑰是非常困難的盆色。10 年前 RSA 密鑰的推薦長度是 1024,但隨著計算機運算能力的提高祟剔,現(xiàn)在 1024 已經(jīng)不安全隔躲,普遍認為至少要 2048 位。

  2. ECC(Elliptic Curve Cryptography)是非對稱加密里的“后起之秀”物延,它基于“橢圓曲線離散對數(shù)”的數(shù)學難題宣旱,使用特定的曲線方程和基點生成公鑰和私鑰,子算法 ECDHE 用于密鑰交換叛薯,ECDSA 用于數(shù)字簽名浑吟。

比起 RSA,ECC 在安全強度和性能上都有明顯的優(yōu)勢耗溜。160 位的 ECC 相當于 1024 位的 RSA组力,而 224 位的 ECC 則相當于 2048 位的 RSA。因為密鑰短抖拴,所以相應的計算量燎字、消耗的內(nèi)存和帶寬也就少,加密解密的性能就上去了阿宅,對于現(xiàn)在的移動互聯(lián)網(wǎng)非常有吸引力候衍。

對稱加密的優(yōu)點是運算速度快,缺點是互聯(lián)網(wǎng)環(huán)境下無法將密鑰安全的傳送給對方洒放。非對稱加密的優(yōu)點是可以安全的將公鑰傳遞給對方脱柱,但是運算速度慢。

看到這里拉馋,你是不是認為可以拋棄對稱加密榨为,只用非對稱加密來實現(xiàn)機密性呢惨好?

這里 TLS 把對稱加密和非對稱加密結(jié)合起來,兩者互相取長補短随闺,即能高效地加密解密日川,又能安全地密鑰交換。其實說穿了也很簡單:

在通信剛開始的時候使用非對稱算法矩乐,比如 RSA龄句、ECDHE,首先解決密鑰交換的問題散罕。

然后用隨機數(shù)產(chǎn)生對稱算法使用的“會話密鑰”(session key)分歇,再用公鑰加密。因為會話密鑰很短欧漱,通常只有 16 字節(jié)或 32 字節(jié)职抡,所以慢一點也無所謂。

對方拿到密文后用私鑰解密误甚,取出會話密鑰缚甩。這樣,雙方就實現(xiàn)了對稱密鑰的安全交換窑邦,后續(xù)就不再使用非對稱加密擅威,全都使用對稱加密。




這樣混合加密就解決了對稱加密算法的密鑰交換問題冈钦,而且安全和性能兼顧郊丛,完美地實現(xiàn)了機密性。

不過這只是“萬里長征的第一步”瞧筛,后面還有完整性宾袜、身份認證、不可否認等特性沒有實現(xiàn)驾窟,所以現(xiàn)在的通信還不是絕對安全庆猫。

數(shù)字簽名與證書

黑客雖然拿不到會話密鑰,無法破解密文绅络,但可以通過竊聽收集到足夠多的密文月培,再嘗試著修改、重組后發(fā)給網(wǎng)站恩急。因為沒有完整性保證杉畜,服務器只能“照單全收”,然后他就可以通過服務器的響應獲取進一步的線索衷恭,最終就會破解出明文此叠。

另外,黑客也可以偽造身份發(fā)布公鑰随珠。如果你拿到了假的公鑰灭袁,混合加密就完全失效了猬错。你以為自己是在和“某寶”通信,實際上網(wǎng)線的另一端卻是黑客茸歧,銀行卡號倦炒、密碼等敏感信息就在“安全”的通信過程中被竊取了。

所以软瞎,在機密性的基礎上還必須加上完整性逢唤、身份認證等特性,才能實現(xiàn)真正的安全涤浇。

摘要算法

實現(xiàn)完整性的手段主要是摘要算法(Digest Algorithm)鳖藕,也就是常說的散列函數(shù)、哈希函數(shù)(Hash Function)只锭。

你可以把摘要算法近似地理解成一種特殊的壓縮算法著恩,它能夠把任意長度的數(shù)據(jù)“壓縮”成固定長度、而且獨一無二的“摘要”字符串纹烹,就好像是給這段數(shù)據(jù)生成了一個數(shù)字“指紋”页滚。

換一個角度召边,也可以把摘要算法理解成特殊的“單向”加密算法铺呵,它只有算法,沒有密鑰隧熙,加密后的數(shù)據(jù)無法解密片挂,不能從摘要逆推出原文。

摘要算法實際上是把數(shù)據(jù)從一個“大空間”映射到了“小空間”贞盯,所以就存在“沖突”(collision音念,也叫碰撞)的可能性,就如同現(xiàn)實中的指紋一樣躏敢,可能會有兩份不同的原文對應相同的摘要闷愤。好的摘要算法必須能夠“抵抗沖突”,讓這種可能性盡量地小件余。

因為摘要算法對輸入具有“單向性”和“雪崩效應”讥脐,輸入的微小不同會導致輸出的劇烈變化,所以也被 TLS 用來生成偽隨機數(shù)(PRF啼器,pseudo random function)旬渠。

你一定在日常工作中聽過、或者用過 MD5(Message-Digest 5)端壳、SHA-1(Secure Hash Algorithm 1)告丢,它們就是最常用的兩個摘要算法,能夠生成 16 字節(jié)和 20 字節(jié)長度的數(shù)字摘要损谦。但這兩個算法的安全強度比較低岖免,不夠安全岳颇,在 TLS 里已經(jīng)被禁止使用了。

目前 TLS 推薦使用的是 SHA-1 的后繼者:SHA-2觅捆。

SHA-2 實際上是一系列摘要算法的統(tǒng)稱赦役,總共有 6 種,常用的有 SHA224栅炒、SHA256掂摔、SHA384,分別能夠生成 28 字節(jié)赢赊、32 字節(jié)乙漓、48 字節(jié)的摘要。

完整性

摘要算法保證了“數(shù)字摘要”和原文是完全等價的释移。所以叭披,我們只要在原文后附上它的摘要,就能夠保證數(shù)據(jù)的完整性玩讳。

比如涩蜘,你發(fā)了條消息:“轉(zhuǎn)賬 1000 元”,然后再加上一個 SHA-2 的摘要熏纯。網(wǎng)站收到后也計算一下消息的摘要同诫,把這兩份“指紋”做個對比,如果一致樟澜,就說明消息是完整可信的误窖,沒有被修改。

如果黑客在中間哪怕改動了一個標點符號秩贰,摘要也會完全不同霹俺,網(wǎng)站計算比對就會發(fā)現(xiàn)消息被竄改,是不可信的毒费。

不過摘要算法不具有機密性丙唧,如果明文傳輸,那么黑客可以修改消息后把摘要也一起改了觅玻,網(wǎng)站還是鑒別不出完整性想际。

所以,真正的完整性必須要建立在機密性之上串塑,在混合加密系統(tǒng)里用會話密鑰加密消息和摘要沼琉,這樣黑客無法得知明文,也就沒有辦法動手腳了桩匪。

這有個術語打瘪,叫哈希消息認證碼(HMAC)。

數(shù)字簽名

加密算法結(jié)合摘要算法,我們的通信過程可以說是比較安全了闺骚。但這里還有漏洞彩扔,就是通信的兩個端點(endpoint)。

就像一開始所說的僻爽,黑客可以偽裝成網(wǎng)站來竊取信息虫碉。而反過來,他也可以偽裝成你胸梆,向網(wǎng)站發(fā)送支付敦捧、轉(zhuǎn)賬等消息,網(wǎng)站沒有辦法確認你的身份碰镜,錢可能就這么被偷走了兢卵。

現(xiàn)實生活中,解決身份認證的手段是簽名和印章绪颖,只要在紙上寫下簽名或者蓋個章秽荤,就能夠證明這份文件確實是由本人而不是其他人發(fā)出的。

在這里柠横,使用非對稱加密里的“私鑰”再加上摘要算法窃款,就能夠?qū)崿F(xiàn)“數(shù)字簽名”,同時實現(xiàn)“身份認證”和“不可否認”牍氛。

數(shù)字簽名的原理其實很簡單晨继,就是把公鑰私鑰的用法反過來,之前是公鑰加密糜俗、私鑰解密踱稍,現(xiàn)在是私鑰加密曲饱、公鑰解密悠抹。

但又因為非對稱加密效率太低,所以私鑰只加密原文的摘要扩淀,這樣運算量就小的多楔敌,而且得到的數(shù)字簽名也很小,方便保管和傳輸驻谆。

簽名和公鑰一樣完全公開卵凑,任何人都可以獲取。但這個簽名只有用私鑰對應的公鑰才能解開胜臊,拿到摘要后勺卢,再比對原文驗證完整性,就可以像簽署文件一樣證明消息確實是你發(fā)的象对。

剛才的這兩個行為也有專用術語黑忱,叫做“簽名”和“驗簽”。

只要你和網(wǎng)站互相交換公鑰,就可以用“簽名”和“驗簽”來確認消息的真實性甫煞,因為私鑰保密菇曲,黑客不能偽造簽名,就能夠保證通信雙方的身份抚吠。

比如常潮,你用自己的私鑰簽名一個消息“我是小明”。網(wǎng)站收到后用你的公鑰驗簽楷力,確認身份沒問題喊式,于是也用它的私鑰簽名消息“我是某寶”。你收到后再用它的公鑰驗一下萧朝,也沒問題垃帅,這樣你和網(wǎng)站就都知道對方不是假冒的,后面就可以用混合加密進行安全通信了剪勿。

數(shù)字證書和 CA

到現(xiàn)在贸诚,綜合使用對稱加密、非對稱加密和摘要算法厕吉,是不是已經(jīng)完美了呢酱固?

不是的,這里還有一個“公鑰的信任”問題头朱。因為誰都可以發(fā)布公鑰运悲,我們還缺少防止黑客偽造公鑰的手段,也就是說项钮,怎么來判斷這個公鑰就是你或者某寶的公鑰呢班眯?

真是“按下葫蘆又起了瓢”,安全還真是個麻煩事啊烁巫,“一環(huán)套一環(huán)”的署隘。

我們可以用類似密鑰交換的方法來解決公鑰認證問題,用別的私鑰來給公鑰簽名亚隙,顯然磁餐,這又會陷入“無窮遞歸”。但這次實在是“沒招”了阿弃,要終結(jié)這個“死循環(huán)”诊霹,就必須引入“外力”,找一個公認的可信第三方渣淳,讓它作為“信任的起點脾还,遞歸的終點”,構(gòu)建起公鑰的信任鏈入愧。

這個“第三方”就是我們常說的 CA(Certificate Authority鄙漏,證書認證機構(gòu))赛蔫。它就像網(wǎng)絡世界里的公安局、教育部泥张、公證中心呵恢,具有極高的可信度,由它來給各個公鑰簽名媚创,用自身的信譽來保證公鑰無法偽造渗钉,是可信的。CA 對公鑰的簽名認證也是有格式的钞钙,不是簡單地把公鑰綁定在持有者身份上就完事了鳄橘,還要包含序列號、用途芒炼、頒發(fā)者瘫怜、有效時間等等,把這些打成一個包再簽名本刽,完整地證明公鑰關聯(lián)的各種信息鲸湃,形成“數(shù)字證書”(Certificate)。

知名的 CA 全世界就那么幾家子寓,比如 DigiCert暗挑、VeriSign坎缭、Entrust轻掩、Let’s Encrypt 等,它們簽發(fā)的證書分 DV碱妆、OV鲜屏、EV 三種烹看,區(qū)別在于可信程度。

DV 是最低的洛史,只是域名級別的可信惯殊,背后是誰不知道。EV 是最高的虹菲,經(jīng)過了法律和審計的嚴格核查靠胜,可以證明網(wǎng)站擁有者的身份(在瀏覽器地址欄會顯示出公司的名字掉瞳,例如 Apple毕源、GitHub 的網(wǎng)站)。

不過陕习,CA 怎么證明自己呢霎褐?

這還是信任鏈的問題。小一點的 CA 可以讓大 CA 簽名認證该镣,但鏈條的最后冻璃,也就是Root CA,就只能自己證明自己了,這個就叫“自簽名證書”(Self-Signed Certificate)或者“根證書”(Root Certificate)省艳。你必須相信娘纷,否則整個證書信任鏈就走不下去了。

有了這個證書體系跋炕,操作系統(tǒng)和瀏覽器都內(nèi)置了各大 CA 的根證書赖晶,上網(wǎng)的時候只要服務器發(fā)過來它的證書,就可以驗證證書里的簽名辐烂,順著證書鏈(Certificate Chain)一層層地驗證遏插,直到找到根證書,就能夠確定證書是可信的纠修,從而里面的公鑰也是可信的胳嘲。

證書體系的弱點

證書體系(PKI,Public Key Infrastructure)雖然是目前整個網(wǎng)絡世界的安全基礎設施扣草,但絕對的安全是不存在的了牛,它也有弱點,還是關鍵的“信任”二字辰妙。

如果 CA 失誤或者被欺騙白魂,簽發(fā)了錯誤的證書,雖然證書是真的上岗,可它代表的網(wǎng)站卻是假的福荸。

還有一種更危險的情況,CA 被黑客攻陷肴掷,或者 CA 有惡意敬锐,因為它(即根證書)是信任的源頭,整個信任鏈里的所有證書也就都不可信了呆瞻。

這兩種事情并不是“聳人聽聞”台夺,都曾經(jīng)實際出現(xiàn)過。所以痴脾,需要再給證書體系打上一些補丁颤介。

針對第一種,開發(fā)出了 CRL(證書吊銷列表赞赖,Certificate revocation list)和 OCSP(在線證書狀態(tài)協(xié)議滚朵,Online Certificate Status Protocol),及時廢止有問題的證書前域。

對于第二種辕近,因為涉及的證書太多,就只能操作系統(tǒng)或者瀏覽器從根上“下狠手”了匿垄,撤銷對 CA 的信任移宅,列入“黑名單”归粉,這樣它頒發(fā)的所有證書就都會被認為是不安全的。

HTTPS 建立連接

當你在瀏覽器地址欄里鍵入“https”開頭的 URI漏峰,再按下回車糠悼,會發(fā)生什么呢?

瀏覽器首先要從 URI 里提取出協(xié)議名和域名浅乔。因為協(xié)議名是“https”绢掰,所以瀏覽器就知道了端口號是默認的 443,它再用 DNS 解析域名童擎,得到目標的 IP 地址滴劲,然后就可以使用三次握手與網(wǎng)站建立 TCP 連接了。

在 HTTP 協(xié)議里顾复,建立連接后班挖,瀏覽器會立即發(fā)送請求報文。但現(xiàn)在是 HTTPS 協(xié)議芯砸,它需要再用另外一個“握手”過程萧芙,在 TCP 上建立安全連接,之后才是收發(fā) HTTP 報文假丧。

這個“握手”過程與 TCP 有些類似双揪,是 HTTPS 和 TLS 協(xié)議里最重要、最核心的部分包帚,懂了它渔期,你就可以自豪地說自己“掌握了 HTTPS”。

TLS 協(xié)議的組成

在講 TLS 握手之前渴邦,我先簡單介紹一下 TLS 協(xié)議的組成疯趟。

TLS 包含幾個子協(xié)議,你也可以理解為它是由幾個不同職責的模塊組成谋梭,比較常用的有記錄協(xié)議信峻、警報協(xié)議、握手協(xié)議瓮床、變更密碼規(guī)范協(xié)議等盹舞。

  1. 記錄協(xié)議(Record Protocol)規(guī)定了 TLS 收發(fā)數(shù)據(jù)的基本單位:記錄(record)。它有點像是 TCP 里的 segment隘庄,所有的其他子協(xié)議都需要通過記錄協(xié)議發(fā)出踢步。但多個記錄數(shù)據(jù)可以在一個 TCP 包里一次性發(fā)出,也并不需要像 TCP 那樣返回 ACK峭沦。

  2. 警報協(xié)議(Alert Protocol)的職責是向?qū)Ψ桨l(fā)出警報信息贾虽,有點像是 HTTP 協(xié)議里的狀態(tài)碼。比如吼鱼,protocol_version 就是不支持舊版本蓬豁,bad_certificate 就是證書有問題,收到警報后另一方可以選擇繼續(xù)菇肃,也可以立即終止連接地粪。

  3. 握手協(xié)議(Handshake Protocol)是 TLS 里最復雜的子協(xié)議,要比 TCP 的 SYN/ACK 復雜的多琐谤,瀏覽器和服務器會在握手過程中協(xié)商 TLS 版本號蟆技、隨機數(shù)、密碼套件等信息斗忌,然后交換證書和密鑰參數(shù)质礼,最終雙方協(xié)商得到會話密鑰,用于后續(xù)的混合加密系統(tǒng)织阳。

  4. 最后一個是變更密碼規(guī)范協(xié)議(Change Cipher Spec Protocol)眶蕉,它非常簡單,就是一個“通知”唧躲,告訴對方造挽,后續(xù)的數(shù)據(jù)都將使用加密保護。那么反過來弄痹,在它之前饭入,數(shù)據(jù)都是明文的。

下面的這張圖簡要地描述了 TLS 的握手過程肛真,其中每一個“框”都是一個記錄谐丢,多個記錄組合成一個 TCP 包發(fā)送。所以蚓让,最多經(jīng)過兩次消息往返(4 個消息)就可以完成握手庇谆,然后就可以在安全的通信環(huán)境里發(fā)送 HTTP 報文,實現(xiàn) HTTPS 協(xié)議凭疮。

ECDHE 握手過程

剛才你看到的是握手過程的簡要圖饭耳,又畫了一個詳細圖,下面我就用這個圖來仔細剖析 TLS 的握手過程执解。

在 TCP 建立連接之后寞肖,瀏覽器會首先發(fā)一個“Client Hello”消息,也就是跟服務器“打招呼”衰腌。里面有客戶端的版本號新蟆、支持的密碼套件,還有一個隨機數(shù)(Client Random)右蕊,用于后續(xù)生成會話密鑰琼稻。

Handshake Protocol: Client Hello

Version: TLS 1.2 (0x0303)

Random: 1cbf803321fd2623408dfe…

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)這個的意思就是:“我這邊有這些這些信息,你看看哪些是能用的饶囚,關鍵的隨機數(shù)可得留著帕翻○梗”復制代碼

作為“禮尚往來”,服務器收到“Client Hello”后嘀掸,會返回一個“Server Hello”消息紫岩。把版本號對一下,也給出一個隨機數(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ā)送“Server Key Exchange”消息衅鹿,里面是橢圓曲線的公鑰(Server Params)撒踪,用來實現(xiàn)密鑰交換算法,再加上自己的私鑰簽名認證大渤。

Handshake Protocol: Server Key Exchange

EC Diffie-Hellman Server Params

Curve Type: named_curve (0x03)

Named Curve: x25519 (0x001d)

Pubkey: 3b39deaf00217894e...

Signature Algorithm: rsa_pkcs1_sha512 (0x0601)

Signature: 37141adac38ea4...這相當于說:“剛才我選的密碼套件有點復雜制妄,所以再給你個算法的參數(shù),和剛才的隨機數(shù)一樣有用泵三,別丟了耕捞。為了防止別人冒充,我又蓋了個章烫幕“吵椋”復制代碼

之后是“Server Hello Done”消息,服務器說:“我的信息就是這些较曼,打招呼完畢磷斧。”

這樣第一個消息往返就結(jié)束了(兩個 TCP 包),結(jié)果是客戶端和服務器通過明文共享了三個信息:Client Random弛饭、Server Random 和 Server Params冕末。

客戶端這時也拿到了服務器的證書,那這個證書是不是真實有效的呢孩哑?

這就要用到第 25 講里的知識了栓霜,開始走證書鏈逐級驗證翠桦,確認證書的真實性横蜒,再用證書公鑰驗證簽名,就確認了服務器的身份:“剛才跟我打招呼的不是騙子销凑,可以接著往下走丛晌。”

然后斗幼,客戶端按照密碼套件的要求澎蛛,也生成一個橢圓曲線的公鑰(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”宿百,所以也就得不到主密鑰。

為什么非得這么麻煩虹蓄,非要三個隨機數(shù)呢犀呼?

這就必須說 TLS 的設計者考慮得非常周到了,他們不信任客戶端或服務器偽隨機數(shù)的可靠性薇组,為了保證真正的“完全隨機”“不可預測”外臂,把三個不可靠的隨機數(shù)混合起來,那么“隨機”的程度就非常高了律胀,足夠讓黑客難以猜測宋光。

你一定很想知道“Master Secret”究竟是怎么算出來的吧貌矿,貼一下 RFC 里的公式:

master_secret = PRF(pre_master_secret, "master secret",ClientHello.random + ServerHello.random)這里的“PRF”就是偽隨機數(shù)函數(shù),它基于密碼套件里的最后一個參數(shù)罪佳,比如這次的 SHA384逛漫,通過摘要算法來再一次強化“Master Secret”的隨機性。復制代碼

主密鑰有 48 字節(jié)赘艳,但它也不是最終用于通信的會話密鑰酌毡,還會再用 PRF 擴展出更多的密鑰,比如客戶端發(fā)送用的會話密鑰(client_write_key)蕾管、服務器發(fā)送用的會話密鑰(server_write_key)等等枷踏,避免只用一個密鑰帶來的安全隱患。

有了主密鑰和派生的會話密鑰掰曾,握手就快結(jié)束了旭蠕。客戶端發(fā)一個“Change Cipher Spec”旷坦,然后再發(fā)一個“Finished”消息掏熬,把之前所有發(fā)送的數(shù)據(jù)做個摘要,再加密一下秒梅,讓服務器做個驗證旗芬。

意思就是告訴服務器:“后面都改用對稱算法加密通信了啊,用的就是打招呼時說的 AES番电,加密對不對還得你測一下岗屏。”

服務器也是同樣的操作漱办,發(fā)“Change Cipher Spec”和“Finished”消息这刷,雙方都驗證加密解密 OK,握手正式結(jié)束娩井,后面就收發(fā)被加密的 HTTP 請求和響應了暇屋。

RSA 握手過程

整個握手過程可真是夠復雜的,但你可能會問了洞辣,好像這個過程和其他地方看到的不一樣呢咐刨?

剛才說的其實是如今主流的 TLS 握手過程,這與傳統(tǒng)的握手有兩點不同扬霜。

第一個定鸟,使用 ECDHE 實現(xiàn)密鑰交換,而不是 RSA著瓶,所以會在服務器端發(fā)出“Server Key Exchange”消息联予。

第二個,因為使用了 ECDHE,客戶端可以不用等到服務器發(fā)回“Finished”確認握手完畢沸久,立即就發(fā)出 HTTP 報文季眷,省去了一個消息往返的時間浪費。這個叫“TLS False Start”卷胯,意思就是“搶跑”子刮,和“TCP Fast Open”有點像,都是不等連接完全建立就提前發(fā)應用數(shù)據(jù)窑睁,提高傳輸?shù)男省?/p>

這里我也畫了個圖挺峡。

大體的流程沒有變,只是“Pre-Master”不再需要用算法生成卵慰,而是客戶端直接生成隨機數(shù)沙郭,然后用服務器的公鑰加密佛呻,通過“Client Key Exchange”消息發(fā)給服務器裳朋。服務器再用私鑰解密,這樣雙方也實現(xiàn)了共享三個隨機數(shù)吓著,就可以生成主密鑰鲤嫡。

雙向認證

到這里 TLS 握手就基本講完了。

不過上面說的是“單向認證”握手過程绑莺,只認證了服務器的身份暖眼,而沒有認證客戶端的身份。這是因為通常單向認證通過后已經(jīng)建立了安全通信纺裁,用賬號诫肠、密碼等簡單的手段就能夠確認用戶的真實身份。

但為了防止賬號欺缘、密碼被盜栋豫,有的時候(比如網(wǎng)上銀行)還會使用 U 盾給用戶頒發(fā)客戶端證書,實現(xiàn)“雙向認證”谚殊,這樣會更加安全丧鸯。

雙向認證的流程也沒有太多變化,只是在“Server Hello Done”之后嫩絮,“Client Key Exchange”之前丛肢,客戶端要發(fā)送“Client Certificate”消息,服務器收到后也把證書鏈走一遍剿干,驗證客戶端的身份蜂怎。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市置尔,隨后出現(xiàn)的幾起案子杠步,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篮愉,死亡現(xiàn)場離奇詭異腐芍,居然都是意外死亡,警方通過查閱死者的電腦和手機试躏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門猪勇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颠蕴,你說我怎么就攤上這事泣刹。” “怎么了犀被?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵椅您,是天一觀的道長。 經(jīng)常有香客問我寡键,道長掀泳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任西轩,我火速辦了婚禮员舵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藕畔。我一直安慰自己马僻,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布注服。 她就那樣靜靜地躺著韭邓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溶弟。 梳的紋絲不亂的頭發(fā)上女淑,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音可很,去河邊找鬼诗力。 笑死,一個胖子當著我的面吹牛我抠,可吹牛的內(nèi)容都是我干的苇本。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼菜拓,長吁一口氣:“原來是場噩夢啊……” “哼瓣窄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纳鼎,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤俺夕,失蹤者是張志新(化名)和其女友劉穎裳凸,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劝贸,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡姨谷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了映九。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梦湘。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖件甥,靈堂內(nèi)的尸體忽然破棺而出捌议,到底是詐尸還是另有隱情,我是刑警寧澤引有,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布瓣颅,位于F島的核電站,受9級特大地震影響譬正,放射性物質(zhì)發(fā)生泄漏宫补。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一导帝、第九天 我趴在偏房一處隱蔽的房頂上張望守谓。 院中可真熱鬧,春花似錦您单、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凤优,卻和暖如春悦陋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背筑辨。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工俺驶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棍辕。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓暮现,卻偏偏與公主長得像,于是被迫代替她去往敵國和親楚昭。 傳聞我的和親對象是個殘疾皇子栖袋,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容