HTTPS必須在每次請求中都要先在SSL層進行握手傳遞秘鑰嗎?

我們知道https相對於http會更安全,因為它先經過SSL層握手得到公鑰,那麼之後的每一次https請求是否還要經過SSL去獲得公鑰?還是在第一次獲得之後,找了個地方存放了起來?


先糾正題主描述里的欠妥的地方,「因為它先經過SSL層握手得到公鑰」,準確的說,不是公鑰,是通信雙方共同擁有的秘密,一般稱之為「Pre-Master Key」。

是的,瀏覽器可以session ID為單位臨時保存加密key等安全參數。

瀏覽器客戶端訪問同一個https伺服器,可以不必每次都進行完整的TLS Handshake,因為完整的TLS Handshake,涉及到認證伺服器的身份(數字證書),需要做大量的非對稱加密/解密運算,此外還需要做偽隨機函數PRF,通過「Pre-Master Key」、「Server Nonce」、「Client Nonce」共同推導出session key非對稱加密演算法RSA/DSA非常耗費CPU資源。

為了克服這個困難,伺服器維護一個以session ID為索引的結構體,用於臨時存放session key,並在TLS handshake 階段分享給瀏覽器

當瀏覽器重新連接https 伺服器時,TLS handshake 階段,出示自己的session ID,伺服器獲得session ID,以此為索引,可以獲得和該瀏覽器共同擁有的session key,使用session key可以直接對用戶流量做加密/解密動作。

這樣避免了大量的冪、指數計算。

當然,如果伺服器沒有查找到session ID,雙方的TLS安全參數協商按照正常流程走。


不存在公鑰傳遞這一說。

SSL中的密鑰包括2種,分別是管理密鑰和業務密鑰。這兩個密鑰都是對稱密鑰。

在這兩個密鑰協商出來以前,是一個認證的環節。認證中,公私鑰並不是最重要的部分,最重要的部分是證書籤名。證書一個是證明你是背書過的,一個是驗證你是持有私鑰的。

至於證書是不是需要每次都呈上,有2個考慮:

  1. 如果開啟了TLS快速恢復,那麼上次斷鏈前,伺服器可以給客戶端發放一個token,通過驗證token達到雙向驗證,不需要經過ssl的一堆呈上憑證的過程。這種情況下不需要重新呈上證書。
  2. 伺服器端是分散式的,可能同一個域名有很多證書對應,也就是說,谷歌可能被簽署了大量的證書,分給每個分散式的節點。和你做驗證的伺服器節點可能有很多個(怎麼區分呢?私鑰吃有者)。基於這種考慮,因為你拿上次A節點的公鑰去驗證B節點的私鑰(雖然都是谷歌域名證書),是不能通過的。這時,每次鏈接都要重新呈上憑據供客戶端驗證。

HTTP協議本身的定義是沒有連接的,就是每個請求都要重新連接,那麼HTTPS也需要重新進行整個協商過程,效率很低

但是HTTP協議後來加了一個重要的選項,就是keep alive,這樣的話一個TCP連接,可以保持一段時間,比如60秒。這樣TCP連接建立好,TLS會話協商好之後,可以重複被多個HTTP請求使用

這樣效率就高很多了


建立鏈接時用的是非對稱密鑰,這個過程會協商一個對稱密鑰用於會話,後續的會話用剛剛生成的對稱密鑰加密數據。
協商對稱密鑰的簡單過程是:客戶端發送一個隨機數給服務端,服務端收到後也發送一個隨機數給客戶端,客戶端收到後再生成第三個隨機數,第三個隨機數用服務端的公鑰加密後發送給服務端,服務端用私鑰解密得到第三個隨機數。服務端和客戶端手握三個隨機數然後各自生成會話密鑰進行會話加密。


現在主流TLS協商會話密鑰的方式都是Perfect Forward secrecy, 比如ECDHE。每次TLS握手都產生臨時公鑰,每次的TLS會話的對稱加密密鑰都不一樣。Firefox/Chrome瀏覽器里會把會話密鑰保存在環境變數SSLKEYLOGFILE中。


先補充說明一下SSL握手過程(演算法列表,完整性鑒別,不重數...等細節略)

客戶端獲取證書取得伺服器公鑰僅僅只是一個開始,之後客戶端利用這個公鑰發送給伺服器一個PMS(Pre-Master Secret 前主密鑰),雙方共享了這個PMS之後利用特定的演算法導出這次會話所要使用的對稱密鑰,然後這次對話的數據全都用這個對稱密鑰加密(非對稱加密的計算開銷太大,不能大量使用)

是否每次HTTPS請求都要進行SSL握手?

並不是。SSL是邏輯上獨立於運輸層的,並且是面向連接的,所以不管進行幾次https請求,也不管tcp連接有沒有更新,只要客戶和伺服器的SSL連接沒有終止並且雙方沒有丟失這段SSL連接的識別號,客戶和伺服器之間就可以一直使用握手階段生成的對稱密鑰進行應用層通信。只有重新進行SSL連接時才會再握手。


推薦閱讀:

TLS 1.2 基於DH是如何交換密鑰?
Fiddler抓取https原理?
請教SSL握手過程中,為什麼抓包找不到pre-master-key?
上經過ssl加密的網站,為什麼有的顯示公司名,有的不顯示?

TAG:JavaScript | 網路安全 | SSL | HTTPS | 計算機科學 |