SSL/TLS協議運行機制的概述
互聯網的通信安全,建立在 SSL/TLS 協議之上。
本文簡要介紹 SSL/TLS 協議的運行機制。文章的重點是設計思想和運行過程,不涉及具體的實現細節。如果想了解這方面的內容,請參閱 RFC 文檔。
一、作用
不使用 SSL/TLS 的 HTTP 通信,就是不加密的通信。所有信息明文傳播,帶來了三大風險。
(1) 竊聽風險(eavesdropping):第三方可以獲知通信內容。
(2) 篡改風險(tampering):第三方可以修改通信內容。
(3) 冒充風險(pretending):第三方可以冒充他人身份參與通信。
SSL/TLS 協議是為了解決這三大風險而設計的,希望達到:
(1) 所有信息都是加密傳播,第三方無法竊聽。
(2) 具有校驗機制,一旦被篡改,通信雙方會立刻發現。
(3) 配備身份證書,防止身份被冒充。
互聯網是開放環境,通信雙方都是未知身份,這為協議的設計帶來了很大的難度。而且,協議還必須能夠經受所有匪夷所思的攻擊,這使得 SSL/TLS 協議變得異常復雜。
二、歷史
互聯網加密通信協議的歷史,幾乎與互聯網一樣長。
1994 年,NetScape 公司設計了 SSL 協議(Secure Sockets Layer)的 1.0 版,但是未發布。
1995 年,NetScape 公司發布 SSL 2.0 版,很快發現有嚴重漏洞。
1996 年,SSL 3.0 版問世,得到大規模應用。
1999 年,互聯網標準化組織 ISOC 接替 NetScape 公司,發布了 SSL 的升級版 TLS 1. 0 版。
2006 年和 2008 年,TLS 進行了兩次升級,分別為 TLS 1.1 版和 TLS 1.2 版。最新的變動是 2011 年 TLS 1.2 的修訂版。
目前,應用最廣泛的是 TLS 1.0,接下來是 SSL 3.0。但是,主流瀏覽器都已經實現了 TLS 1.2 的支持。
TLS 1.0 通常被標示為 SSL 3.1,TLS 1.1 為 SSL 3.2,TLS 1.2 為 SSL 3.3。
三、基本的運行過程
SSL/TLS 協議的基本思路是采用公鑰加密法,也就是說,客戶端先向服務器端索要公鑰,然后用公鑰加密信息,服務器收到密文后,用自己的私鑰解密。
但是,這里有兩個問題。
(1)如何保證公鑰不被篡改?
解決方法:將公鑰放在數字證書中。只要證書是可信的,公鑰就是可信的。
(2)公鑰加密計算量太大,如何減少耗用的時間?
解決方法:每一次對話(session),客戶端和服務器端都生成一個"對話密鑰"(session key),用它來加密信息。由于"對話密鑰"是對稱加密,所以運算速度非常快,而服務器公鑰只用于加密"對話密鑰"本身,這樣就減少了加密運算的消耗時間。
因此,SSL/TLS 協議的基本過程是這樣的:
(1) 客戶端向服務器端索要并驗證公鑰。
(2) 雙方協商生成"對話密鑰"。
(3) 雙方采用"對話密鑰"進行加密通信。
上面過程的前兩步,又稱為"握手階段"(handshake)。
四、握手階段的詳細過程
"握手階段"涉及四次通信,我們一個個來看。需要注意的是,"握手階段"的所有通信都是明文的。
4. 1 客戶端發出請求(ClientHello)
首先,客戶端(通常是瀏覽器)先向服務器發出加密通信的請求,這被叫做 ClientHello 請求。
在這一步,客戶端主要向服務器提供以下信息。
(1) 支持的協議版本,比如 TLS 1.0 版。
(2) 一個客戶端生成的隨機數,稍后用于生成"對話密鑰"。
(3) 支持的加密方法,比如 RSA 公鑰加密。
(4) 支持的壓縮方法。
這里需要注意的是,客戶端發送的信息之中不包括服務器的域名。也就是說,理論上服務器只能包含一個網站,否則會分不清應該向客戶端提供哪一個網站的數字證書。這就是為什么通常一臺服務器只能有一張數字證書的原因。
對于虛擬主機的用戶來說,這當然很不方便。2006 年,TLS 協議加入了一個 Server Name Indication 擴展,允許客戶端向服務器提供它所請求的域名。
4. 2 服務器回應(SeverHello)
服務器收到客戶端請求后,向客戶端發出回應,這叫做 SeverHello。服務器的回應包含以下內容。
(1) 確認使用的加密通信協議版本,比如 TLS 1.0 版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信。
(2) 一個服務器生成的隨機數,稍后用于生成"對話密鑰"。
(3) 確認使用的加密方法,比如 RSA 公鑰加密。
(4) 服務器證書。
除了上面這些信息,如果服務器需要確認客戶端的身份,就會再包含一項請求,要求客戶端提供"客戶端證書"。比如,金融機構往往只允許認證客戶連入自己的網絡,就會向正式客戶提供 USB 密鑰,里面就包含了一張客戶端證書。
4. 3 客戶端回應
客戶端收到服務器回應以后,首先驗證服務器證書。如果證書不是可信機構頒布、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。
如果證書沒有問題,客戶端就會從證書中取出服務器的公鑰。然后,向服務器發送下面三項信息。
(1) 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽。
(2) 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(3) 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的 hash 值,用來供服務器校驗。
上面第一項的隨機數,是整個握手階段出現的第三個隨機數,又稱"pre-master key"。有了它以后,客戶端和服務器就同時有了三個隨機數,接著雙方就用事先商定的加密方法,各自生成本次會話所用的同一把"會話密鑰"。
至于為什么一定要用三個隨機數,來生成"會話密鑰",dog250解釋得很好:
"不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由于 SSL 協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對于 RSA 密鑰交換算法來說,pre-master-key 本身就是一個隨機數,再加上 hello 消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master 的存在在于 SSL 協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那么 pre master secret 就有可能被猜出來,那么僅適用 pre master secret 作為密鑰就不合適了,因此必須引入新的隨機因素,那么客戶端和服務器加上 pre master secret 三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。"
此外,如果前一步,服務器要求客戶端證書,客戶端會在這一步發送證書及相關信息。
4. 4 服務器的最后回應
服務器收到客戶端的第三個隨機數 pre-master key 之后,計算生成本次會話所用的"會話密鑰"。然后,向客戶端最后發送下面信息。
(1)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(2)服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是前面發送的所有內容的 hash 值,用來供客戶端校驗。
至此,整個握手階段全部結束。接下來,客戶端與服務器進入加密通信,就完全是使用普通的 HTTP 協議,只不過用"會話密鑰"加密內容。
五、參考鏈接
- MicroSoft TechNet, SSL/TLS in Detail
- Jeff Moser, The First Few Milliseconds of an HTTPS Connection
- Wikipedia, Transport Layer Security
- StackExchange, How does SSL work?
<span id="shareA4" class="fl"> </span>