HTTPs入門, 圖解SSL從回車到握手

大家在網路衝浪時, 在訪問一些涉及金融/支付/登錄/後台等敏感業務時, 會發現這些網站都會重定向到 https:// 的 URL , 例如:

  • 地址為綠色, 表示安全且可信任;

  • 地址為紅色, 則表示雖然開啟了加密, 但網站身份未驗證, 無法保證不被中間人嗅探.

從我們在地址欄敲下 https:// 網站那一剎那, 到內容顯示到我們面前, 中間經過了哪些過程了? 瀏覽器根據什麼來判斷, 當前網站網址是安全的還是未驗證的? 這篇文章可幫助你了解到這些. 考慮到個人知識所限, 難免有遺漏或錯誤之處, 如你有發現, 請在下面留言指出.

圖示:

講解:

1. Client-hello 階段

瀏覽器中完成地址輸入後, 解析域名獲得 IP Host 地址, 瀏覽器會與此 Host 的443(默認, 如果指定其他埠則會連接此埠) 嘗試連接, 也就是 TLS 握手協議的 Client-hello, 上圖的第一步.

瀏覽器會將"支持的加密組件"/"嘗試連接到Host頭"等信息發送給伺服器, 並會附上一份隨機生成的 session ticket1.

2. Server-hello 階段

伺服器收到瀏覽器發送來的 TLS 握手請求後, 存儲瀏覽器發送的session ticket2, 然後根據發送來的 host 尋找對於的伺服器證書, 然後會將伺服器證書, 伺服器與瀏覽器妥協(均支持)的加密套件方法, 和一份隨機生成的 session ticket 返回給瀏覽器.

3. Cipher-spec 階段

瀏覽器收到伺服器返回的證書後, 會驗證證書有效性. 驗證步驟大概如下:

  • 驗證證書有效期(起止時間)
  • 驗證證書域名(與瀏覽器地址欄中域名是否匹配)
  • 驗證證書吊銷狀態(CRL+OCSP), [見本文後"吊銷檢查"章節].
  • 驗證證書頒發機構, 如果頒發機構是中間證書, 在驗證中間證書的有效期/頒發機構/吊銷狀態. 一直驗證到最後一層證書, 如果最後一層證書是在操作系統或瀏覽器內置, 那麼就是可信的, 否則就是自簽名. [見本文後"簽發者"章節]

以上驗證步驟, 需要全部通過. 否則就會顯示警告.

若檢查通過, 隨機生成一份 session ticket 3 (這是瀏覽器生成的第二份 ticket), 通過返回證書中的公鑰, 用協商的"秘鑰交換演算法"加密, 返回給伺服器.

同時瀏覽器用 session ticket 1(瀏) & session ticket 2(服) & session ticket 3(瀏) 組合成 session key.

伺服器收到 Ciper-spec 後, 用配置的私鑰, 解密出 session ticket3, 用 session ticket 1(瀏) & session ticket 2(服) & session ticket 3(瀏) 組合成 session key.

此處不難得知, 伺服器與瀏覽器交換的最終秘鑰, session key全等且未泄露(session ticket 1 和 session ticket 2可以抓包, 但session ticket 3是無法竊聽的).

為什麼session ticket 3無法竊聽?

有個 webtrust 組織, 專門負責備案世界上各國商業與政府官方 CA 機構的公鑰證書. 如果審計通過, 其他瀏覽器及操作系統/客戶端才允許加入信任列表. 否則是不允許加入的. 如果中間人攔截了 session ticket 3 的響應密文, 沒有私鑰, 中間攻擊人是解密不了的. 而要想拿到私鑰, 攻擊人可以做到, 就是在客戶端和伺服器中間搭建代理, 替換掉 SSL 證書, 以實現伺服器返回證書時候中間替換自己的, 從而在中間攔截伺服器和客戶端兩頭的通信.

但是如果這樣做, 瀏覽器和客戶端會顯示非信任的頒發者, 如下圖 chrome 和 curl 命令行下分別警告:

4. 內容傳輸階段

至此, TLS 連接建立完成, 在連接銷毀前, 瀏覽器與伺服器彼此數據均通過 session key 來進行對稱加密.

通過

上述過程, 其實是別有用心的, 因為非對稱加密非常消耗 CPU. 所以只有在協商秘鑰時候使用非對稱加密, 而應用層數據交換就用協商成功的秘鑰作為私鑰對稱加密傳輸(伺服器響應的加密返回, 客戶端提交的也加密提交).

吊銷檢查:

目前寫進國際標準的吊銷狀態檢查協議有兩種: 1.CRL, 2. OCSP

CRL 是一份全量的文件, 記錄了被此 CRL 限制的證書中所有被吊銷證書的序列號. 通過匹配當前證書序列號, 與 CRL 中序列號, 來判斷.

  • 有點繞, 反正就說, 所有打上了這個 URL 的 CRL 的證書, 只要其中一個被吊銷, 那麼下次 CRL 更新時, 均會查詢匹配到.
  • 那麼可不可以認為一個中間頒發機構頒發的證書的 CRL 列表只有一個? 不可以! 因為數量可能太多, 廠商完全可以將同一個中間證書頒發的最終證書, 分不同批打不同的 CRL.

而 OCSP 是 TCP 服務, 通過請求證書序列號, 伺服器告知當前序列號是否在被吊銷名單.

有的證書內置了 CRL+OCSP, 有點只內置了 OCSP, 還有的早起證書只內置了 CRL, 但只內置 CRL 的證書是不被新型瀏覽器信任了.

請思考:

問: 吊銷狀態檢查, 是同步的還是非同步的?

答案: 同步的.

如果非同步檢查, 有可能會導致瀏覽器發送數據給了未驗證的主機後, 過了一段時間才檢查出來證書已吊銷. 所以, 必須同步

簽發者:

證書的簽發者, 通過以下步驟獲得

1. 伺服器證書, 如果包含了證書鏈, 瀏覽器會嘗試匹配(根據當前證書的"簽發者公鑰"匹配鏈中的後續證書的"公鑰"), 如果匹配失敗, 走2.

2. 中如果有聲明 簽發者 URL, 瀏覽器嘗試下載. 並通過公鑰匹配(同1), 如果匹配失敗, 走3

3. 操作系統或客戶端瀏覽器內置證書公鑰匹配, 如果匹配失敗, 則返回ERR_CERT_AUTORITY_INVALID.

4. 附加項: 如果任何一級證書, 被聲明了 oID, 則會被瀏覽器顯示成 EV(綠色地址欄帶上公司名稱).

題外話:

問: HTTPS 是否會拖慢性能?

答案: 看具體部署的情況.

瀏覽器在加密 session ticket3時, 和伺服器在接受瀏覽器返回 session ticket3時, 是非對稱加密中可能出現耗時的步驟. 但這個步驟頂多幾毫秒, 並且現代化瀏覽器和 NGINX 已經支持 session 復用, 造成的性能損耗幾乎可以忽略不計.

而真正可能拖慢性能的, 只可能是在吊銷檢查步驟中.

因為上面說了, 吊銷狀態檢查只能是同步的, 那麼受到 CA 廠商的部署限制, 極可能會將 CRL 伺服器和 OCSP 伺服器部署在遙遠的小機房, 帶寬/鏈路都是極差的, 這種, DNS 解析和連接 CRL/OCSP 伺服器均需要耗時, 此過程的損耗, 是一大批在知乎的所謂專家所言的加密解密過程損耗的數十倍到數百倍.

問: 怎麼規避吊銷狀態帶來的損耗?

答案: 仁者見仁, 智者見智. 這裡給出兩個建議

1. 踩上大廠的順風車. 如百度阿里騰訊和蘋果微軟操作系統各種常見網站和軟體的伺服器/代碼簽名證書, 均有 CRL 和 OCSP, 而 CRL 是操作系統層復用的, 只要在 TTL 時間內, 操作系統檢查過對應 CA 的 CRL, 那麼 CRL 均可避免二次下載, 用戶訪問就可實現加速. OCSP 也至少可以搭上一個免去 DNS 解析的紅利. 例如 Symantec/GeoTrust/GlobalSign

2. 買國內 CA 的證書. 我指的是真正自己在瀏覽器根證書的 CA 啊,不包括僅僅是中間證書分銷商, 也不包括前面被除名然後變成分銷商的WoSign.

問: 12306的證書部署, 除了 CA 不受信任外, 還有那些錯誤?

答: 除了 CA 不受信任, 還存在問題:

  1. 沒有吊銷狀態聲明, 根據最新的 webtrust 標準, 沒有聲明吊銷狀態的證書不受信任.
  2. 簽名演算法用了過期的 SHA-1.

推薦閱讀:

SSL的那些事兒
HTTPS必須在每次請求中都要先在SSL層進行握手傳遞秘鑰嗎?
為什麼SSL證書那麼貴?

TAG:信息安全 | SSL | HTTPS |