“握手”是建立一個(gè)HTTPS連接過(guò)程的專(zhuān)業(yè)術(shù)語(yǔ)。涉及SSL/TLS的大部分困難工作都在此步完成。
一個(gè)HTTPS連接涉及兩方:客戶(hù)端(發(fā)起連接的一方,通常是你的瀏覽器)和服務(wù)器。另一方就是“握手”的人。SSL握手的目的是實(shí)施一個(gè)安全連接所需的所有加密工作。這包括SSL證書(shū)使用的驗證以及生成一個(gè)密鑰。
由于達成這一目的的每一個(gè)步驟所用到的軟件都是不同的,握手的第一步就是讓客戶(hù)端和服務(wù)器共用彼此的性能,以發(fā)現他們共同支持的加密功能。瀏覽器是最常見(jiàn)的客戶(hù)端,而諸如Chrome、火狐、IE等不同瀏覽器的功能也互不相同。類(lèi)似地,在服務(wù)器端,諸如Windows Server、Apache、NGINX等常見(jiàn)操作系統也有著(zhù)不同的性能支持。
一旦客戶(hù)端和服務(wù)器在他們使用的具體加密方法上達成一致,服務(wù)器就會(huì )向客戶(hù)端發(fā)送它的SSL證書(shū)??蛻?hù)端會(huì )檢驗以確認證書(shū)是“可信的”,這是一個(gè)極其重要的步驟。為真正建立一個(gè)安全連接,你不能只是加密你的數據,還要確保數據被發(fā)送到正確的人或地點(diǎn)。SSL證書(shū)提供了這種保證。
SSL證書(shū)是由證書(shū)頒發(fā)機構(CA)創(chuàng )建并簽發(fā)的,這種機構是被批準頒發(fā)證書(shū)的公司。你可能知道其中一些比較著(zhù)名的機構,如 Symantec和Comodo。CA遵守行業(yè)標準,確保你只能得到你真正擁有的網(wǎng)站或公司的證書(shū)。
在握手期間,客戶(hù)端將進(jìn)行加密安全檢驗來(lái)確保服務(wù)器提供的證書(shū)是可信的。這包括檢驗數字簽名并確保證書(shū)來(lái)自于一個(gè)可信的CA。
客戶(hù)端也會(huì )得到服務(wù)器擁有與此證書(shū)相關(guān)的私鑰的證明。所有SSL證書(shū)都包含一對密鑰,密匙由一個(gè)公鑰和一個(gè)私鑰組成。公鑰用于加密數據,私鑰則用于解密。這稱(chēng)為“不對稱(chēng)”加密,因為兩個(gè)功能由不同的密鑰來(lái)執行。
就最常見(jiàn)的密鑰類(lèi)型RSA來(lái)說(shuō),客戶(hù)端會(huì )以公鑰加密隨機數據,用該公鑰生成會(huì )話(huà)密鑰。只有當服務(wù)器有私鑰提供所有權證明的情況下,才能解密并使用該數據。如果使用另一類(lèi)型的密鑰,這個(gè)過(guò)程就變了,但總是需要檢驗所有權證明的。
握手的最后一部分涉及創(chuàng )建“會(huì )話(huà)密鑰”,這實(shí)際上是用于安全通信的密鑰。會(huì )話(huà)密鑰是“對稱(chēng)”的,也就是說(shuō)相同的密鑰既用于加密也用于解密。這樣的密鑰能實(shí)現強加密性,其有效性大大超過(guò)不對稱(chēng)密鑰,這使得它們適于在HTTPS連接中來(lái)回發(fā)送數據。
為結束握手,每一方都要使對方知道他們完成了所有必要的工作,然后雙方都進(jìn)行檢驗以確保握手過(guò)程中沒(méi)有任何惡意篡改和破壞。整個(gè)握手發(fā)生在幾百毫秒時(shí)間內。它是HTTPS連接中必須發(fā)生的第一件事,甚至要早于網(wǎng)頁(yè)的加載。
一旦握手完成,已加密和驗證過(guò)的HTTPS連接就開(kāi)始了,所有在你和服務(wù)器之間被發(fā)送和接收的數據都受到保護。每次你重新訪(fǎng)問(wèn)一個(gè)網(wǎng)站的時(shí)候,握手都將重復發(fā)生。為了實(shí)現更高的效率和速度,很多服務(wù)器會(huì )執行一個(gè)“繼續”過(guò)程。
握手包含一系列步驟,完成三個(gè)主要任務(wù),我們將其概括為:交換加密功能、驗證SSL證書(shū)和交換/生成會(huì )話(huà)密鑰。希望了解具體過(guò)程的讀者請看備注[1]。注意,在即將到來(lái)的TLS1.3中,握手設計發(fā)生了變化,因此這些步驟不適用于TLS1.3。
下圖闡釋了這些步驟,左側是客戶(hù)端,右側是服務(wù)器。[2]每一步都有箭頭標識出接收消息的一方。
第一個(gè)消息是“客戶(hù)端問(wèn)候”,是發(fā)送給服務(wù)器的。這條消息展示出客戶(hù)端具備的性能,這樣服務(wù)器就可以選擇怎樣進(jìn)行通信。
服務(wù)器以“服務(wù)器問(wèn)候”消息作回應。這條消息,告知了客戶(hù)端它從列表中選擇的連接參數。如果客戶(hù)端和服務(wù)器不具備任何共同的性能,連接就將被終止。
在“證書(shū)”消息中,服務(wù)器發(fā)送它的SSL證書(shū)鏈(包括它的葉子證書(shū)和中間證書(shū))到客戶(hù)端。與加密同樣重要的是,為向連接提供驗證,一個(gè)SSL證書(shū)要由一個(gè)能夠使客戶(hù)端驗證證書(shū)合法性的CA簽發(fā)。然后客戶(hù)端將執行檢驗以確保證書(shū)合法。[3]這包括檢驗證書(shū)的數字簽名、驗證證書(shū)鏈以及對任何可能存在問(wèn)題(如證書(shū)過(guò)期、域名錯誤等)的證書(shū)數據的檢驗??蛻?hù)端也會(huì )確保服務(wù)器有證書(shū)私鑰的所有權。這是在密鑰交換/生成過(guò)程中完成的。
這是一個(gè)可選消息,只有某些要求服務(wù)器提供額外數據的密鑰交換方法才需要。
“服務(wù)器問(wèn)候完成”消息告知客戶(hù)端它的所有消息發(fā)送完畢。
客戶(hù)端也對會(huì )話(huà)密鑰有幫助。這一步的細節取決于在初始“問(wèn)候”消息中就已確定的密鑰交換方法。TLS使用兩種不同密鑰:一個(gè)公鑰/私鑰對(SSL證書(shū)的一部分)和一個(gè)握手期間生成的會(huì )話(huà)密鑰。會(huì )話(huà)密鑰是“對稱(chēng)密鑰”。它是在HTTPS連接期間使用的密鑰,因為相比天然較慢的“不對稱(chēng)”的公鑰/私鑰對,它明顯更快、更高效。公鑰/私鑰對只在會(huì )話(huà)密鑰的安全傳輸的這幾個(gè)步驟中使用。
“更換密碼規范”消息使另一方知道它生成了會(huì )話(huà)密鑰并要轉換到加密通信。
然后發(fā)送“完成”消息,說(shuō)明握手已經(jīng)完成。該消息是加密的,而且是被會(huì )話(huà)密鑰保護的第一個(gè)數據。該消息包含允許雙方確認握手未被篡改的數據。
現在到了服務(wù)器做相同事情的時(shí)候了,服務(wù)器發(fā)送它的“更換密碼規范”消息,表示它要轉換到加密通信。
服務(wù)器發(fā)送“完成”消息。
在這幾步完成后,SSL握手就完成了。雙方現在有了一個(gè)會(huì )話(huà)密鑰并開(kāi)始以一個(gè)加密的和驗證過(guò)的連接進(jìn)行通信。從這時(shí)起,“應用”數據(屬于實(shí)際服務(wù)的數據,也就是網(wǎng)站的HTML、Javascript等)的第一個(gè)字節可以被發(fā)送了。
備注:
[1]注意我們只是在講一個(gè)只涉及服務(wù)器驗證的典型的握手。在TLS中,可能會(huì )有互相驗證,客戶(hù)端也會(huì )提供證書(shū)。但很少使用。
[2]參考文獻:Section 7 & 7.4 of the TLS 1.2 RFC. Chapter 2 of Bulletproof SSL & TLS by Ivan Ristic
[3]注意,TLS的RFC規定證書(shū)驗證應在“服務(wù)器問(wèn)候完成”消息之后進(jìn)行。