為什麼要有 HTTPS?簡單的回答是:「因為 HTTP 不安全」。HTTP 怎麼不安全呢?
只有同時具備了機密性、完整性、身份認證、不可否認這四個特性,才能算得上是安全的通訊。
HTTPS 使用 HTTP 進行通訊,並使用 SSL/TLS 為 HTTP 增加了機密性、完整性、身份認證、不可否認這四大安全特性。
SSL 即安全通訊協定(Secure Sockets Layer)。
SSL 發展到 v3 時已經證明了它是一個非常好的安全通訊協定,於是網際網路工程組 IETF 在 1999 年把 SSL 改名為 TLS(傳輸層安全,Transport Layer Security),正式標準化,版本號從 1.0 重新算起,所以 TLS1.0 實際上就是 SSLv3.1。
至今,TLS 已經發展出了三個版本,分別是 2006 年的 1.1、2008 年的 1.2 和 2018 的 1.3,每個新版本都緊跟密碼學的發展和網際網路的現狀,持續強化安全和效能。目前應用最廣泛的 TLS 版本是 1.2,而之前的版本(TLS1.1 / 1.0、SSLv3 / v2)都已經被認為是不安全的。
TLS 綜合使用了對稱加密、非對稱加密、身份認證等許多密碼學前沿技術。非對稱加密在這個場景中發揮的作用是 「金鑰協商」,通訊的雙方協商得到對談金鑰。對談金鑰用於 HTTP 報文的加解密,以實現機密性。
TLS 由記錄協定、握手協定、警報協定、變更密碼規範協定、擴充套件協定等幾個子協定組成:
通訊的雙方在 TLS 握手的過程中會協商使用的密碼套件(cipher suite,也被稱為加密套件)。
TLS 的密碼套件命名非常規範。固定的格式是:「金鑰交換演演算法 + 簽名演演算法 + 對稱加密演演算法 + 分組模式 + 訊息摘要演演算法」,例如 「ECDHE-RSA-AES256-GCM-SHA384」 密碼套件的意思就是:
金鑰交換演演算法使用的是:ECDHE。通訊的雙方在 TLS 握手的過程中協商 TLS 的版本號、密碼套件,交換亂數、數位憑證和金鑰引數,通訊的雙方使用 ECDHE 演演算法演演算法 "Pre Master Secret"。
簽名演演算法使用的是:RSA。TLS 握手的過程中,使用 RSA 簽名演演算法進行數位簽章。伺服器給瀏覽器傳送 "Server Key Exchange" 訊息,伺服器對金鑰引數(訊息中的 Public 引數)進行數位簽章,然後把簽名值一併行送給瀏覽器。瀏覽器收到 "Server Key Exchange" 訊息後,使用數位憑證中的公鑰對金鑰引數(訊息中的 Public 引數)進行驗籤。
對稱加密演演算法使用的是:AES-256。TLS 握手後的通訊使用 AES 對稱加密演演算法進行加密,以實現機密性。對稱金鑰的長度 256 位
分組模式使用的是:GCM。加密明文的長度不固定,而一次對稱加密只能處理特定長度的一塊資料,這就需要進行迭代,以便將一段很長的資料全部加密,而迭代的方法就是分組模式。
訊息摘要演演算法使用的是:SHA-384。TLS 握手的過程中,兩次用到了該訊息摘要演演算法。一次是:「PRF」 通過訊息摘要演演算法,根據三個亂數(Client Random、Server Random 和 Pre Master Secret)計算主金鑰 "Master Secret" 的值。另一次是:通訊的雙方給對方傳送 "Finished" 訊息。一方對之前傳送的資料做摘要,再使用對談金鑰對摘要進行對稱加密,讓對方進行驗證(類似數位簽章的驗籤)。TLS 握手後的通訊使用該訊息摘要演演算法進行訊息認證,防止訊息被篡改。
使用 HTTPS 協定通訊,通訊的雙方會先建立 TCP 連線,然後執行 TLS 握手,之後就可以在安全的通訊環境裡收發 HTTP 請求和響應了。
執行 TLS 握手的目的是:通訊的雙方安全的協商對談金鑰。對談金鑰用於 HTTP 報文的加解密,以實現機密性。
TLS1.2 握手可以劃分為兩種方式:使用 RSA 演演算法實現金鑰交換 和 使用 ECDHE 演演算法實現金鑰交換。
下面說的是使用 ECDHE 演演算法實現金鑰交換的 TLS 握手過程。
TLS 握手過程的簡要描述:通訊的雙方在 TLS 握手的過程中協商 TLS 的版本號、密碼套件,交換亂數、數位憑證和金鑰引數,最終通訊的雙方協商得到對談金鑰。"Hello" 訊息交換亂數,"Key Exchange" 訊息交換金鑰引數。
TLS 握手的過程如下圖所示,其中每一個框都是一個記錄,多個記錄組合成一個 TCP 包傳送。所以,最多經過兩次訊息往返(4 個訊息,或者說 4 個 TCP 包)就可以完成 TLS 握手。
瀏覽器與伺服器建立 TCP 連線之後,瀏覽器會首先給伺服器傳送 "Client Hello" 訊息。"Client Hello" 訊息攜帶幾個引數:Version、Random、Cipher Suites。
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)
伺服器收到瀏覽器傳送的 "Client Hello" 訊息後,伺服器給瀏覽器傳送 "Server Hello" 訊息。"Server Hello" 訊息攜帶幾個引數:Version、Random、Cipher Suite。
Handshake Protocol: Server Hello
Version: TLS 1.2 (0x0303)
Random: 0e6320f21bae50842e96…
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
伺服器為了向瀏覽器證明自己的身份,伺服器給瀏覽器傳送一個證書鏈,包含了兩個證書。一個是 CA 機構頒發的數位憑證,另一個是 CA 機構的數位憑證。
通過引入數位憑證,實現了伺服器的身份認證功能,這樣即便駭客偽造了伺服器,但是由於數位憑證是沒有辦法偽造的,所以駭客依然無法欺騙使用者。
由於伺服器選擇了使用 ECDHE 金鑰交換演演算法,因此伺服器需要給瀏覽器傳送【伺服器端的橢圓曲線的公鑰】(Server Params)。為了防止公鑰被第三方篡改、被駭客冒充,伺服器會對公鑰進行數位簽章,然後把簽名值一併行送給瀏覽器。瀏覽器收到後,使用數位憑證中的公鑰對金鑰引數(訊息中的 Public 引數)進行驗籤。
伺服器給瀏覽器傳送 "Server Key Exchange" 訊息。"Server Key Exchange" 訊息攜帶幾個引數:Curve Type、Named Curve、Pubkey、Signature Algorithm、Signature。
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...
伺服器給瀏覽器傳送 "Server Key Exchange" 訊息之後,伺服器傳送資訊完畢。伺服器給瀏覽器傳送 "Server Hello Done" 訊息,伺服器向瀏覽器說明:伺服器傳送資訊完畢了。
至此,第一個訊息往返就結束了(2 個訊息,或者說 2 個 TCP 包)。結果是:通訊的雙方通過明文傳輸共用瞭如下資訊:瀏覽器生成的亂數(Client Random)、伺服器生成的亂數(Server Random)、使用的橢圓曲線的型別、伺服器端的橢圓曲線的公鑰(Server Params)。
瀏覽器收到伺服器傳送的數位憑證之後,瀏覽器需要驗證數位憑證是否合法、有效。
瀏覽器驗證完數位憑證合法、有效後,瀏覽器再用數位憑證中的公鑰驗證【伺服器給瀏覽器傳送的 "Server Key Exchange" 訊息】的簽名,以確認伺服器的身份。
瀏覽器確認了伺服器的身份之後,就開始了第二個訊息往返。
由於通訊的雙方協商的使用 ECDHE 金鑰交換演演算法。因此瀏覽器需要給伺服器傳送【使用者端的橢圓曲線的公鑰】(Client Params)。瀏覽器給伺服器傳送 "Client Key Exchange" 訊息。
Handshake Protocol: Client Key Exchange
EC Diffie-Hellman Client Params
Pubkey: 8c674d0e08dc27b5eaa…
至此,通訊的雙方都獲取到了 ECDHE 金鑰交換演演算法需要的兩個引數(Client Params、Server Params),於是通訊的雙方就使用 ECDHE 演演算法算出一個亂數,這個亂數被叫做 "Pre Master Secret"。
ECDHE 演演算法可以保證:即使駭客截獲了之前的引數,駭客也絕對算不出這個 「Pre Master Secret」 亂數,因為 "Pre Master Secret" 的計算還使用了橢圓曲線的私鑰。
目前,通訊的雙方已知三個亂數:Client Random、Server Random 和 Pre Master Secret。通訊的雙方使用這三個亂數作為原始資訊,通過 PRF 算出主金鑰(Master Secret)。因為駭客拿不到 "Pre Master Secret",所以駭客也就無法得到主金鑰。
主金鑰 "Master Secret" 的計算:這裡的 「PRF」 就是偽亂數函數,它基於密碼套件裡的最後一個引數(訊息摘要演演算法),比如 SHA384。「PRF」 通過 SHA384 訊息摘要演演算法再一次強化 "Master Secret" 的隨機性。
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
主金鑰的長度為 48 位元組,但是主金鑰並不是最終用於通訊的對談金鑰,還會再用 PRF 擴充套件出更多的金鑰,比如瀏覽器傳送用的對談金鑰(client_write_key)、伺服器傳送用的對談金鑰(server_write_key)等,避免只用一個金鑰帶來的安全隱患。有了主金鑰和派生的對談金鑰,TLS 握手就快結束了。
瀏覽器給伺服器傳送 "Change Cipher Spec" 訊息。瀏覽器告訴伺服器:瀏覽器後續傳輸的都是對稱金鑰加密的密文。瀏覽器給伺服器傳送 "Finished" 訊息。瀏覽器對之前傳送的資料做摘要,再使用對談金鑰對摘要進行對稱加密,讓伺服器進行驗證(類似數位簽章的驗籤)。
伺服器也進行和瀏覽器同樣的操作。
雙方都驗證成功,握手正式結束,之後就可以正常收發被加密的 HTTP 請求和響應了。
TLS1.2 握手可以劃分為兩種方式:使用 RSA 演演算法實現鑰交換 和 使用 ECDHE 演演算法實現金鑰交換。
上面說了【使用 ECDHE 演演算法實現金鑰交換的 TLS 握手過程】,下面說【使用 RSA 演演算法實現金鑰交換的 TLS 握手過程】。
TLS 握手過程的簡要描述:通訊的雙方在 TLS 握手的過程中協商 TLS 的版本號、密碼套件,交換亂數、數位憑證和金鑰引數,最終通訊的雙方協商得到對談金鑰。"Hello" 訊息交換亂數,"Key Exchange" 訊息交換 "Pre Master Secret"。
【使用 RSA 演演算法實現鑰交換的 TLS 握手過程】的大體流程沒有變,只是 "Pre Master Secret" 不再需要通訊的雙方根據金鑰引數使用演演算法算出,而是由瀏覽器生成,瀏覽器再使用伺服器的公鑰對生成的 "Pre Master Secret" 進行加密。然後,瀏覽器給伺服器傳送 "Server Key Exchange" 訊息,把加密後的 "Pre Master Secret" 傳送給伺服器。伺服器收到瀏覽器傳送的 "Server Key Exchange" 訊息後,使用伺服器的私鑰解密出亂數 "Pre Master Secret"。
這樣通訊的雙方也已知三個亂數:Client Random、Server Random 和 Pre Master Secret,就可以生成主金鑰了。
23 | HTTPS是什麼?SSL/TLS又是什麼? (geekbang.org)
本文來自部落格園,作者:真正的飛魚,轉載請註明原文連結:https://www.cnblogs.com/feiyu2/p/https.html