前置知識
SSL是90年代Netscape弄出來的一套東西,為的是解決HTTP協議明文傳輸數據的問題。后來SSL慢慢成了事實上的標准,於是IETF就把SSL標准化了,名字叫做TLS,TLS 1.0其實就是SSL 3.1。所以SSL和TLS經常被放在一起寫成SSL/TLS,因為這兩個名詞在現在其實就是同一個東西。HTTPS是使用TLS的HTTP協議。
證書以及信任鏈
我們知道,HTTPS的網站都有一個自己的證書,用於表明自己的身份。證書本質上是為了讓公鑰能可信的傳輸。公鑰是放在證書里面的,如果證書可信,那么公鑰就也是可信的。那為什么一個公鑰是可信的呢?這就要說到信任鏈和CA。CA指的是Certificate Authority,CA都是權威機構,他們的證書叫做根證書,這些根證書被操作系統信任,根證書信任的證書也是可信的。因此權威機構頒發的證書都能被操作系統信任,這就組成了信任鏈。
這里以RSA密鑰交換算法為例為例,CloudFlare提供Keyless服務,把網站放到它們的CDN上,不用提供自己的私鑰,也能使用SSL加密鏈接。
https加密解密過程:
-
客戶端發起https請求到服務端(服務器端要一套數字證書,可以自己制作,也可以向組織申請),向服務器端索要公鑰。
發送的信息一般帶上:
-
客戶端生成的一個隨機值
-
支持的SSL/TSL協議的版本號
-
所支持的加密算法
-
Session ID(用於恢復會話)
-
-
服務端接收到客戶端的請求后回應客戶端以及公鑰(也就是證書)傳給客戶端。如果帶有Session ID,直接恢復對話。
沒有Session ID一般會返回這些信息給客戶端:
-
選擇SSL/TLS協議的版本號
-
選擇加密方式
-
一個服務器隨機生成的數
-
服務器的證書
-
-
客戶端收到服務端發來的公鑰后會解析證書,首先是由TLS層來驗證服務端證書是否有效,比如說頒發機構、有效時間、證書中的域名與當前會話域名是否匹配等。
如果發現異常,就會彈出一個警告框,提示證書有問題。
驗證完證書的有效性后,客戶端向服務端發送的信息包括有一下內容:
-
證書校驗沒有問題的話,生成一個premaster secret(另一個隨機值),然后用服務端發過來的證書對該隨機值進行加密。
-
客戶端把加密的隨機值傳回給服務器,加密約定改變,通知服務器,其目的是讓服務端得到這個隨機值,以后客戶端與服務端之間的通信就用協商好的加密方法和密鑰進行加密。
-
客戶端握手結束通知。這個報文也是驗證消息,是前面發送的所有內容的哈希值,用來供服務器校驗。
-
-
服務器用私鑰解密后,得到了客戶端傳過來的隨機值(私鑰),然后對該值進行對稱加密。所謂對稱加密就是,將信息和私鑰通過某種算法混合在一起,除非知道私鑰,否則無法獲得內容,因而客戶端和服務端都知道這個公鑰,只要加密算法夠彪悍,私鑰夠復雜,數據就越安全。
這是握手過程的最后一步,服務器會把以下信息發送給客戶端:
-
加密約定改變通知,通知客戶端,以后的通信都適用協商好的加密方法和密鑰進行加密
-
服務器握手結束通知,該報文也作為校驗消息,供客戶端驗證
-
-
服務端利用這個私鑰加密數據並發送數據給客戶端,加密的數據可以被還原
-
客戶端接收到這份數據后,利用私鑰解密這段數據,於是獲取了加密的內容。即時第三方在數據傳輸的中途獲取了這份數據,沒有私鑰也束手無策
SSL/TLS層是位於應用層和傳輸層之間,應用層的數據不再直接傳遞給傳輸層,而是傳遞給SSL/TLS層,對傳過來的數據進行加密,並增加相應的頭信息。
整個對話過程中(握手階段和其后的對話),服務器的公鑰和私鑰只需要用到一次。這就是CloudFlare能夠提供Keyless服務的根本原因。
某些客戶(比如銀行)想要使用外部CDN,加快自家網站的訪問速度,但是出於安全考慮,不能把私鑰交給CDN服務商。這時,完全可以把私鑰留在自家服務器,只用來解密對話密鑰,其他步驟都讓CDN服務商去完成。
加解密相關知識
對稱加密
對稱加密(也叫私鑰加密)指加密和解密使用相同密鑰的加密算法。有時又叫傳統密碼算法,就是加密密鑰能夠從解密密鑰中推算出來,同時解密密鑰也可以從加密密鑰中推算出來。而在大多數的對稱算法中,加密密鑰和解密密鑰是相同的,所以也稱這種加密算法為秘密密鑰算法或單密鑰算法。
常見的對稱加密有:DES(Data Encryption Standard)、AES(Advanced Encryption Standard)、RC4、IDEA
非對稱加密
與對稱加密算法不同,非對稱加密算法需要兩個密鑰:公開密鑰(public key)和 私有密鑰(private key);並且加密密鑰和解密密鑰是成對出現的。非對稱加密算法在加密和解密過程使用了不同的密鑰,非對稱加密也稱為公鑰加密,在密鑰對中,其中一個密鑰是對外公開的,所有人都可以獲取到,稱為公鑰,其中一個密鑰是不公開的稱為私鑰。
主要算法:RSA、Elgamal、背包算法、Rabin、D-H、ECC(橢圓曲線加密算法)
使用最廣泛的是RSA算法,Elgamal是另一種常用的非對稱加密算法。
RSA性能是非常低的,原因在於尋找大素數、大數計算、數據分割需要耗費很多的CPU周期,所以一般的HTTPS連接只在第一次握手時使用非對稱加密,通過握手交換對稱加密密鑰,在之后的通信走對稱加密。
總結:
服務端用RSA生成公鑰和私鑰,把公鑰放在證書里發送給客戶端,私鑰自己保存
客戶端接收到公鑰后,首先向一個權威的服務器檢查證書的合法性,如果證書合法,客戶端產生一段隨機數,這個隨機數就作為通信的密鑰,我們稱之為對稱密鑰,用公鑰加密這段隨機數,然后發送到服務器
服務器用密鑰解密獲取對稱密鑰,然后,雙方就已對稱密鑰進行加密解密通信了
傳輸服務器的證書(公鑰)時,被別人竊取走了怎么辦?
當然服務器沒有這么笨,傳給客戶端的證書是被加密了的,而且是由第三方權威機構CA的私鑰加密證書,第三方權威機構CA的公鑰維護於(存在於)每個瀏覽器(無論是中間的黑客、真正的請求者,還有服務器)中。這些有CA機構頒發的證書,都是有CA機構加密了的,客戶端或者中間商收到這份CA頒發的證書,都可以解密出服務器的公鑰。
那么,最開始https請求到服務器給的證書(CA機構頒發的)過程中,證書到達客戶端的路上被黑客攔截了,中間的 "笨笨的黑客" 向CA申請了一套自己的證書,把自家的證書發回給那個客戶端,然后通過自己申請的那一套證書的私鑰解密出客戶端發出的信息,通過攔截下來的服務器端的公鑰解密服務端返回給客戶端的信息,在中間的位置竊取信息。當然這種事情不會發生,權威的CA機構頒發的證書是有數字簽名的,任何組織申請的證書都有對應的證書編碼,證書是頒發給誰的,使用者是誰,這些申請者的詳細信息都是被記錄在案,客戶端接收到這份證書后會計算出證書數字簽名,證書的使用者對不上也是沒有用的。
這樣,通過權威的CA機構和證書的數字簽名,客戶端和服務器端之間建立起的對話秘鑰就不會被別人竊取走,即時中間的第三者拿到了服務器的公鑰也沒有辦法解密用服務器公鑰加密的內容。