HTTPS (HyperText Transfer Protocol over SecureSocket Layer,基於 SSL 的超文本傳輸與協議),是以安全為目標的 HTTP 通道,在 HTTP 的基礎上通過身份認證和傳輸加密保證了傳輸過程的安全性。HTTPS 在 HTTP 的基礎下加入 SSL/TLS(Transport Layer Security,傳輸層安全協議),HTTPS 的安全基礎是 SSL/TLS,因此加密的詳細內容就需要 SSL/TLS。 HTTPS(443 端口) 存在不同於 HTTP(80 端口) 的默認端口及一個傳輸加密 / 身份認證層(在 HTTP 與 TCP 之間)。這個系統提供了身份驗證與加密通訊方法。它被廣泛用於萬維網上安全敏感的通訊,例如交易支付等方面。
加密算法
作為前置知識,先來了解一下兩種常用的加密方式:
-
對稱加密:加密和解密使用相同的秘鑰,加密算法是公開的,秘鑰是絕對保密的。
-
非對稱加密:加密和解密使用不同的秘鑰,加密算法是公開的,公鑰是也是公開的,私鑰是絕對保密的。
HTTPS 在數字證書驗證的時候,采用的 RSA(三個發明者的首字母縮寫) 密碼算法就是一種非對稱加密。這種非對稱加密算法最大的特點是,通過公鑰加密的密文只有對應的私鑰才能解密,同樣通過私鑰加密的密文也只有對應的公鑰才能解密,即公鑰和私鑰互相解密。下面我們將會講到 HTTPS 是如何通過 RSA 這種密碼算法去驗證身份的。
數字證書
數字證書(Digital Certificate)是 HTTPS 實現安全傳輸的基礎,它是由權威的 CA(Certificate Authority,證書認證) 機構頒發的,證書的主要內容有:簽名算法(Certificate Signature Algorithm)、頒發者(Issuer)、有效期(Validity)、使用者(Subject)、公鑰(Public Key)、指紋(Fingerprint)及指紋算法(Fingerprint Algorithm)。
知名的網站都會向權威 CA 機構申請 SSL 數字證書,以增強網站安全性、防止釣魚網站、提高用戶信任度、獲得更高的搜索排名。下面以 Edge 瀏覽器為例,先來看一下數字證書長啥樣,之后再解析數字證書是如何進行安全認證的。
- 點擊網址前面的小鎖圖標,然后選擇連接安全:
如果小鎖是打開的,表示該網站沒有啟用 HTTPS 訪問或者數字證書不被信任。
-
點擊證書圖標,打開證書對話框:
如下,顯示的是證書概覽信息:
-
點擊證書路徑,雙擊證書即可查看詳情:
可以看到證書鏈:權威 CA 機構的根證書(DigiCert)->中繼證書(Encryption Everywhere)->博客園網站證書(*.cnblogs.com)。 -
點擊詳細信息:
可以看到簽名算法、簽名哈希算法(指紋算法)、頒發者、有效期、使用者、公鑰(RSA 2048 Bits)。還有一個指紋在最下面,就不截圖了,它是用來保證數字證書的完整性的,后面會說到。
既然證書都是由權威的 CA 機構頒發的,那么 CA 機構的證書是由誰頒發的呢?聰明的你可能已經想到,是 CA 機構自己給自己頒發的,也就是我們上面說的根證書。
再思考一個問題,每次進行證書校驗的時候,都需要向 CA 機構申請它的根證書么?當然不是了,由於 CA 機構的根證書一般都是 20 年以上的有效期,所以將其內置到瀏覽器中,就不用每次都向 CA 機構獲取根證書了。以 Edge 為例,查看瀏覽器內置的根證書步驟如下:
打開設置,搜索證書:
可以看到我們導入的證書,包括內置的根證書:
證書的完整性
在上面博客園的證書中可以看到有一個叫指紋的字符串,指紋可以理解為證書身份的唯一代表,是用來保證證書的完整性(Integrity)的,即證書沒有被修改過。證書在發布之前,CA 機構對證書的內容用指紋算法(一般是 SHA1 或 SHA256)計算得到一個 hash 值,這個 hash 值就是指紋。為什么用 hash 值作為證書的身份代表呢?
- hash 值具有不可逆性,也就是說無法通過 hash 值得出原來的信息內容;
- hash 值具有唯一性,即 hash 計算可以保證不同的內容一定得到不同的 hash 值(其實哈希算法存在哈希碰撞的可能性,但是 SHA1 的 hash 值有 160 位,碰撞概率很小,可以忽略不計)。
簽名是在信息后面加上的一段數字串,可以證明該信息有沒有被修改過。數字證書在發布的時候,CA 機構將證書的指紋和指紋算法通過自己的私鑰加密得到的就是證書的簽名了。
證書的驗證
下面基於一個簡單的圖例,去分析 HTTPS 的數字證書的驗證過程(具體的過程請參考文末博客):
-
我們訪問 HTTPS 網址,瀏覽器向服務器發送 HTTPS 請求(包含對稱加密算法套件)來建立連接,服務器收到 HTTPS 請求后,給瀏覽器返回選擇的對稱加密算法和自己的證書。
-
瀏覽器接收到證書以后,就要開始進行身份認證工作了。首先從證書中得知證書的頒發機構,然后從瀏覽器系統中去尋找此頒發機構的根證書:
- 若能找到根證書,則從根證書中取得那個根公鑰,用根公鑰去解密此證書的數字簽名(根私鑰加密的),成功解密的話就得到證書的指紋(記為 h1,代表根證書的原始內容)和指紋算法;然后用指紋算法對當前接收到的證書內容再進行一次 hash 計算得到另一個值 h2,代表當前證書的內容,如果此時 h2 和 h1 是相等的,就代表證書沒有被修改過。
- 若不能找到根證書,則代表此機構不是受信任的,那么就會警告無法確認證書的真假(小鎖圖標不是閉合的)。
-
在證書沒有被修篡改的基礎上,再檢查證書上的使用者的 URL(比如 cnblogs.com)和我們請求的 URL 是否相等,如果相等,那么就可以證明當前瀏覽器地址欄的網址也是正確的,而不是一些釣魚網站之類的。
到這里我們認證了三點信息:- 證書是否為受信任的權威機構頒發的;
- 證書是否被第三方篡改過;
- 證書是否為服務器發送的。
-
對稱加密算法相關參數互相傳遞后,雙方都能根據自己和對方的參數生成一個相同的對稱加密秘鑰,然后就可以進行加密通信了。
總結
數字證書的驗證有兩個重要的步驟:
- 客戶端驗證服務器發的數字證書有沒有被篡改,以及沒有被篡改的證書是否為服務器發的證書,而不是任何第三方假冒服務器發的證書;
- 客戶端將對稱加密算法的參數安全地發送給服務器。
這兩步都完成以后,整個 HTTPS 的數字證書驗證就算是成功了。
一般情況下只需要客戶端(瀏覽器)認證服務器端,即單向認證,相對的還有一個雙向認證。雙向認證,顧名思義,客戶端和服務器端都需要驗證對方的身份,在建立 HTTPS 連接的過程中,握手的流程比單向認證多了幾步。單向認證的過程,客戶端從服務器端下載服務器端公鑰證書進行驗證,然后建立安全通信通道。雙向通信流程,客戶端除了需要從服務器端下載服務器的公鑰證書進行驗證外,還需要把客戶端的公鑰證書上傳到服務器端給服務器端進行驗證,等雙方都認證通過了,才開始建立安全通信通道進行數據傳輸。