HTTPS是什麼
我們知道HTTP是明文傳輸的,惡意的中間人和竊聽者通過擷取使用者傳送的網路資料包可以拿到使用者的敏感資訊。尤其是涉及網上交易,銀行轉賬等操作更是危害極大。
HTTPS的核心是SSL/TLS安全協議層,該層位於應用層和傳輸層之間,TLS對應用層資料加密後再向下交給傳輸層,以解決HTTP安全傳輸的問題。
下面我們就一起來梳理一下TLS在背後做了哪些事情,為我們的網際網路行業保駕護航。
身份驗證
傳送方與接收方在決定資料傳輸之前,第一步要做的必然是互相確認對方的身份。TLS使用數字證書幫助確認證書持有者的身份。
證書
證書是一數字形式的身份證明,通常由CA進行頒發。證書中包含了證書持有者的資訊,有效期,公鑰,序列號,以及證書頒發者的數字簽名。
CA
CA(Certificate Authority),數字證書認證機構是負責發放和管理數字證書的權威機構,並作為電子商務交易中受信任的第三方,承擔公鑰體系中公鑰的合法性檢驗的責任。
CA的作用可以用公安局來做個類比,負責給公民頒發居民身份證,身份證上的資訊都是公安局簽字確認過的,具有權威性。
數字簽名
數字簽名是非對稱加密技術的另一項應用。它的原理非常簡單:公私鑰是成對使用的,使用私鑰加密的密文,只能使用公鑰來解密。因為私鑰只有特定伺服器才知道,所以如果公鑰可以解密用私鑰加密的密文,必然證明是該伺服器傳送的。私鑰用來數字簽名,表明報文是特定伺服器傳送的;公鑰用來驗證數字簽名。
數字簽名是使用私鑰加密的校驗和。將數字簽名附加到報文上,一併發給接收方。
數字簽名的作用:
- 證明是作者編寫了這條報文;
- 可以防止報文被篡改。
描述一下整個身份驗證的過程:
- 客戶端向伺服器發起請求
- 伺服器將CA發給自己的證書傳送給客戶端
- 客戶端在本機查詢該CA是否在本機的CA列表中
- 如果存在,客戶端使用該CA的公鑰對該證書上的CA數字簽名進行驗證
- 如果驗證通過,說明該證書確實是CA頒發的。
- 客戶端檢視證書是否在有效期,證書上的資訊是否與當前訪問的域名一致。
- 如果確認一致,則證明該證書屬於該伺服器所有。
加密
TLS需要解決的問題是安全地交換對稱金鑰,使用對稱金鑰進行資料的加解密。
加密有兩種主要的技術:對稱金鑰加密和公開金鑰加密。 這兩種加密技術,TLS都在使用。
對稱金鑰
在對稱金鑰加密中,金鑰既用於加密也用於解密。訊息交換的雙方需要同時知道該金鑰。對稱金鑰加密常用於大資料量的加解密,相比非對稱金鑰加密,它的加密速度要快得多。常見的對稱金鑰加密演算法有DES
,3-DES
,RC2
,RC4
,和AES
。
公開金鑰加密
公開金鑰加密是一組金鑰對,由複雜的數學運算得出。其中一個金鑰對外公開稱之為公鑰,通常金鑰持有者讓CA把自己的公鑰寫到證書中對外發布。另一把金鑰由持有者祕密儲存。兩把金鑰一起協作,一把用來加密,另一把用來解密:如果公鑰用來加密,那麼只有對應的私鑰能解密;如果私鑰用來加密,同樣只有對應的公鑰才能解密。這種特殊的關係使得公開金鑰加密有兩種重要的應用。首先,任何一個取得了伺服器公鑰的人,都可以用該公鑰加密資料,同時只有該伺服器私鑰的擁有者才可以進行解密。其次,如果伺服器使用私鑰加密資料,那麼任何取得該伺服器公鑰的人都可以對伺服器傳送的資料進行解密。這也是數字簽名的實現基礎。最常見的演算法是RSA
。
加密技術 | 優點 | 缺點 |
---|---|---|
對稱金鑰 | 加解密速度快,效能好 | 金鑰交換有洩露風險 |
公開金鑰 | 不存在金鑰交換竊取的風險;可以用作簽名驗證身份 | 計算複雜,效能差 |
TLS使用公鑰加密對伺服器進行身份驗證後,在客戶端和伺服器之間商定對稱金鑰。隨後使用商定的對稱金鑰加密會話過程中的大量資料。這種方案既利用公鑰加密解決了身份驗證和金鑰交換的問題,又結合了對稱金鑰加密大量資料速度快的優點。
安全會話建立的完整過程
以上我們已經對TLS的功能和實現方式有了一個初步的瞭解。接下來,我們將對安全會話建立的細節做一個詳細的介紹。
整個安全會話的建立,TLS是以握手的過程來協商的,具體過程下圖所示:
可以看到握手協議通過一系列的有序的訊息協商資料會話所需的安全引數。
客戶端先傳送訊息啟動握手
Client Hello
客戶端向伺服器傳送Client Hello
以發起會話,Client Hello
包含以下資訊:
- 版本號。客戶端可以支援的最高版本的協議。
- 隨機數。長度為32位元組的隨機數。由4位元組的客戶端時間加28位元組的隨機陣列成。
- sessionID。sessionID用來恢復之前的會話。恢復之前的會話很有必要,因為建立新的安全會話,需處理器進行密集的計算得到會話金鑰。通過sessionID恢復已有的會話可以避免此問題。
- 加密套裝。客戶端可以支援的加密套裝列表。例如TLS_RSA_WITH_DES_CBC_SHA,
TLS
是協議的版本,RSA
是金鑰交換的非對稱加密演算法,DES_CBC
是對稱加密演算法,SHA
是雜湊方法。 - 壓縮演算法。客戶端支援的壓縮演算法。
如下是一個 Client Hello訊息的示例:
ClientVersion 3,1
ClientRandom[32]
SessionID: None (new session)
Suggested Cipher Suites:
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
Suggested Compression Algorithm: NONE
複製程式碼
伺服器響應
伺服器收到客戶端的hello訊息後,同樣以hello訊息應答:
Server Hello
伺服器向客戶端傳送Server Hello
,該訊息包括以下內容:
- 版本號。
- 隨機數。伺服器端隨機數,由伺服器時間+隨機陣列成。與客戶端隨機數一起生成
master key
。master key
用來生成會話金鑰。 - sessionID。用來恢復會話。有三種情況:
- 新sessionID。客戶端沒有指明sessionID,伺服器返回一個新的sessionID。如果客戶端指明瞭sessionID,但是伺服器無法恢復對應的會話,也會重新生成一個sessionID。
- 恢復的sessionID。客戶端指明要恢復的sessionID,同時伺服器可以恢復該會話。
- 無。是新的會話,但伺服器不希望將來恢復該會話,所以不返回sessionID。
- 加密套裝。伺服器選擇一個伺服器和客戶端都支援的最強的加密套裝。如果沒有彼此都支援的加密套裝,那麼會結束會話,傳送一個握手失敗的警告。
- 壓縮演算法。指定選用的壓縮演算法。
下面是一個Server Hello
訊息的例子:
Version 3,1
ServerRandom[32]
SessionID: bd608869f0c629767ea7e3ebf7a63bdcffb0ef58b1b941e6b0c044acb6820a77
Use Cipher Suite:
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Compression Algorithm: NONE
複製程式碼
Server Certificate
伺服器向客戶端傳送證書。伺服器證書包含了伺服器的公鑰。客戶端使用伺服器公鑰驗證伺服器的身份,對premaster secret
加密。
客戶端還會檢查證書上宣告的伺服器名字。該名字必須與客戶端正在訪問的伺服器名稱匹配。例如,使用者在瀏覽器中輸如daojia.com
,那麼該證書中的伺服器名必須是daojia.com
或*.daojia.com
。如果兩者不匹配,瀏覽器會給使用者警告。
Server Key Exchange
可選項,伺服器建立並向客戶端傳送一個暫時的金鑰。該金鑰可用於加密Client Key Exchange
訊息。該步驟只有在公鑰演算法沒提供必要的金鑰生成元素時才需要,例如當伺服器證書中沒有公鑰時。
Client Certificate Request
可選項,當伺服器需要客戶端提要身份證明時需要。該步驟適用於那些在提供敏感資訊之前需要客戶端驗證自己身份的網站(例如銀行站點)。
Server Hello Done
該資訊表示伺服器響應完成了,正在等待客戶端響應。
客戶端響應
伺服器回覆結束,客戶端開始應答,應答訊息如下:
Client Certificate
如果伺服器向客戶端請求證書,客戶端需要傳送自己的證書給伺服器,以驗證自己的身份。客戶端證書中有客戶端的公鑰。
Client Key Exchange
客戶端根據hello訊息中傳送的隨機數計算出premaster secret
,使用伺服器公鑰對其加密後傳送給伺服器。
premaster secret
非常重要,因為客戶端和伺服器需要用它和前邊的隨機數,在本地獨立計算master secret
,然後基於master secret
生成會話金鑰,會話金鑰就是安全傳輸時資料加密的對稱金鑰。
Certificate Verify
客戶端使用私鑰對目前為止所有的訊息進行hash計算後進行簽名。接收者使用簽名者的公鑰驗證簽名,確保它是客戶端私鑰籤的名。只有當伺服器請求客戶端證書時才需要傳送該訊息。
Change Cipher Spec
該訊息通知伺服器此後的所有資訊都將使用商定的金鑰和演算法進行加密。
Client Finished
該訊息是先前的握手訊息的加密校驗和。使用hash函式計算所有握手訊息的hash值,然後使用會話金鑰進行加密後作為該訊息的內容。
伺服器響應
Change Cipher Spec Message
該訊息通知客戶端伺服器將使用剛剛協商的金鑰加密資料。
Server Finished
與Client Finished
類似,該訊息是整個握手訊息的hash值,hash值使用會話金鑰加密處理。如果客戶端能成功解密和驗證包含的hash值,那麼可以證明握手是成功的,客戶端計算出的金鑰和伺服器計算出來金鑰匹配。
伺服器響應完成後,整個握手環節結束。一切正常的話,安全會話建立成功,https安全連線建立成功,客戶端和伺服器接下來可以安全地傳輸應用層資料了。
完整的握手過程描述:
- 客戶端向伺服器傳送
Client hello
,向伺服器傳送客戶端隨機數和支援的加密工具。 - 伺服器傳送
Server hello
響應客戶端,向客戶端傳送伺服器隨機數。 - 伺服器將證書傳送給客戶端,有的伺服器還可能請求客戶端證書。
- 如果伺服器請求客戶端證書,客戶端需要傳送證書給伺服器。
- 客戶端建立隨機的
pre-master secret
,使用伺服器證書中提供的公鑰進行加密後,傳送給伺服器。 - 伺服器收到
pre-master secret
。客戶端和伺服器基於pre-master secret
獨立生成master key
和 會話金鑰。 - 客戶端傳送
Change cipher spec
通知伺服器自己接下來要使用兩邊協商好的會話金鑰加密資料了。客戶端還需要傳送Client finished
訊息。 - 伺服器收到
Change cipher spec
後,開始使用會話金鑰對資料加密。伺服器傳送Server finished
訊息給客戶端。 - 至此通訊雙方可以使用建立的安全通道進行資料傳輸了。兩邊傳送的所有資訊都是經過會話金鑰加密過的。
如何避免多次繁複的握手過程
如果每次https連線都要進行這麼長的協商過程效率太低,因此tls支援基於sessionID儲存會話,以便下次訪問時快速恢復會話。
在完整的安全會話協商過程中,伺服器向客戶端傳送了一個sessionID。隨後,客戶端在ClientHello訊息中攜帶sessionID,這意味著客戶端還記得之前與伺服器商定的加密套裝和金鑰。如果伺服器也記得的話,會在ServerHello訊息中攜帶sessionID。
簡化的過程如下:
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
複製程式碼
握手過程描述:
- 客戶端向伺服器傳送
Client hello
訊息,不過訊息中帶上需要恢復的會話的sessionID。 - 伺服器查詢自己的快取,如果找到了匹配的sessionID,並且可以恢復,則向客戶端傳送帶有sessionID的
Server hello
訊息。 - 客戶端和伺服器互相交換
Change cipher spec
訊息,並且傳送Client finished
和Server finished
。 - 客戶端和伺服器恢復安全會話。
通常瀏覽器開啟HTTPS連線時需要完整的握手過程,隨後對同一個伺服器的請求進行快速握手。伺服器通常15s後會關閉非活動狀態的連線,但是會話資訊一般儲存的時間很久(數小時甚至幾天)。
總結
https協議解決安全傳輸的核心是TLS協議。TLS在解決安全傳輸時主要處理的問題就是身份識別和金鑰交換。這兩個問題的解決依賴於公開金鑰加密技術。以公開金鑰加密技術為基礎的數字證書系統是網際網路安全傳輸的基石,是信任鏈的根基。
囉囉嗦嗦寫了很多,目的還是希望能把細節交待的更清楚,能把一些生澀的術語講的相對易懂一些,如果大家還是有些地方看的不清楚,可以在留言互動。