TLS、SSL、CA 證書、公鑰、私鑰。。。今天捋一捋!

架構師修行手冊發表於2023-03-17

來源:江南一點雨


松哥最近在和小夥伴們連載 gRPC,如何確保 gRPC 通訊的安全性?這就涉及到 TSL 了,但是考慮到可能有小夥伴對加密連線這一整套方案比較陌生,因此我們今天先用一篇文章跟大家捋清楚這些概念,概念搞明白了,再來看 TSL+gRPC 就很容易了。

1. HTTP 的問題

HTTP 協議是超文字傳輸協議(Hyper Text Transfer Protocol)的縮寫,它是從 WEB 伺服器傳輸超文字標記語言 HTML 到本地瀏覽器的傳送協議。HTTP 設計之初是為了提供一種釋出和接收 HTML 頁面的方法,時至今日,它的作用已經不僅僅於此了。

對於我們 Java 工程師而言,HTTP 應該算是再熟悉不過的東西了,目前 HTTP 有多個版本,使用較多的是 HTTP/1.1 版本。

然而 HTTP 協議有一個缺陷那就是它是透過明文傳輸資料的,使用者透過 HTTP 協議傳輸的內容很容易被惡意攔截,並且駭客可以偽裝成服務端,向使用者傳送錯誤的資訊,並且能輕易獲取使用者的隱私資訊,而這些操作使用者是完全無感知的。

由於存在這樣的安全隱患,現在小夥伴們見到的大部分網站都在逐步轉為 HTTPS,HTTP 網站會越來越少了。

2. HTTPS

HTTPS(HyperText Transfer Protocol Secure)中文譯作超文字傳輸安全協議,這是一種透過計算機網路進行安全通訊的傳輸協議。

HTTPS 本質上還是由 HTTP 進行通訊,只是在 HTTP 協議和 TCP 層之間增加了一個 SSL 的安全傳輸協議。整個傳輸的加密過程都在新的安全層 SSL/TLS 中實現,而原來的 HTTP 層的傳輸流程保持不變,這樣就很好地相容了舊的 HTTP 協議,也沿襲了 TCP/IP 協議族的分層思想。

透過 HTTPS,客戶端可以確認服務端的身份,保證資料在傳輸過程中不被篡改,當我們在自己的瀏覽器上與某一個網站建立 HTTPS 連線的時候,滿足如下情況可以表示這個服務端可以被信任:

  1. 首先我們的作業系統中安裝了正確且受信任的證照。我們在 cmd 命令列中執行 certmgr.msc 命令,可以檢視作業系統已經安裝的證照列表。
TLS、SSL、CA 證書、公鑰、私鑰。。。今天捋一捋!
  1. 瀏覽器本身正確實現了 HTTPS。
  2. 被訪問的網站提供了一個證照,這個證照是由一個作業系統所信任的證照頒發機構簽發的,作業系統所信任的證照頒發機構一般都預裝在作業系統中,透過第一步的方式可以檢視。
  3. 被訪問的網站所提供的證照被成功認證。

這裡邊涉及到一些證照和協議的概念,接下來松哥和大家把整個過程捋一捋。

3. TLS/SSL

前面我們提到,HTTPS 就是在 HTTP 的基礎之上增加了 TLS/SSL,那麼這兩個東西該如何理解呢?

SSL/TLS 是一種密碼通訊方案,算是目前使用最廣泛的密碼通訊方案了。SSL 全稱是 Secure Socket Layer,中文譯作安全套接層,是 1994 年由 Netscape 公司設計的一套協議,並與 1995 年釋出了 3.0 版本;TLS 全稱是 Transport Layer Security,中文譯作傳輸層安全,則是 IETF 在 SSL3.0 基礎上設計的協議,實際上相當於 SSL 的後續版本,目前 TLS 先後迭代了 TLS 1.0TLS 1.1TLS 1.2TLS 1.3,目前被廣泛使用的是 TLS 1.2 版本。

SSL/TLS 涉及到了密碼學中的對稱加密、非對稱加密、數字簽名等等,算是密碼學領域裡的集大成者了。

3.1 TLS

接下來我們就來看看 TLS 如何確保 HTTP 安全。

為了確保客戶端和服務端之間的資料安全,我們很容易想到一種方案就是對傳輸的資料進行加密,沒錯,這是一個辦法,事實上也是這麼做的。

加密又分為兩種:

  1. 對稱加密
  2. 非對稱加密

那麼該使用哪一種呢?

對稱加密,也就是加密金鑰和解密金鑰是同一個,當瀏覽器和服務端需要進行通訊的時候,約定好一個金鑰,然後使用這個金鑰對傳送的訊息進行加密,對方收到訊息之後再使用相同的金鑰對訊息進行解密。但是,在 B/S 架構的專案中,這種方案顯然不合適,一個網站把自己的金鑰告訴全世界所有的瀏覽器,那加密和不加密還有區別嗎?

有小夥伴可能又想到了不對稱加密,不對稱加密倒是個辦法,因為不對稱加密是有一個金鑰對公鑰和私鑰,公鑰可以公佈出來告訴所有人,私鑰只有自己知道。通訊的時候,客戶端首先使用公鑰對訊息進行加密,服務端收到之後,再透過私鑰對訊息進行解密,這看起來似乎挺完美的。但是!!!非對稱加密存在一個問題,就是非對稱加密和解密相當耗時,透過這種方式處理加解密效率太低。

那怎麼辦?我們可以將兩者結合起來。

具體來說,就是這樣:首先服務端會生成一個非對稱加密的金鑰對,私鑰自己儲存,公鑰傳送給客戶端,客戶端拿到這個公鑰之後,再生成一個對稱加密的金鑰,然後把對稱加密的金鑰透過公鑰進行加密,加密之後傳送給服務端,服務端透過私鑰進行解密,這樣客戶端和服務端就可以透過對稱加密進行通訊了。

事實上,TLS 大致上的思路就是這樣的。

不過上面這個方案還是有一個漏洞,那就是服務端要透過明文傳輸的方式把公鑰傳送給客戶端,這個過程還是不安全的,可能被人惡意截胡,那麼這個問題該如何解決呢?

這就涉及到另外一個概念叫做數字證照了。

3.2 CA

數字證照是一個包含了目標網站各種資訊如網站域名、證照有效期、簽發機構、用於生成對稱金鑰的公鑰、上級證照籤發的簽名等的檔案,透過數字證照我們可以確認一個使用者或者服務站點的身份。

實際場景中的數字證照是一系列的,形成了一個信任鏈,信任鏈的最頂端是 CA。

CA 是 Certificate Authority 的簡寫,它是一個負責發放和管理數字的證照的第三方權威機構。CA 的工作流程是這樣的:

  1. CA 自己給自己頒發的用自己的私鑰簽名的證照稱為根證照,根證照的私鑰安全性至關重要,根證照的私鑰都是被儲存在離線計算機中,有嚴格的操作規章,每次需要使用時,會有專人將資料透過 USB 複製過去,操作完了以後,再將資料帶出來(這個專指 CA 根證照的私鑰)。
  2. 一個使用者想要獲取一個證照,首先自己得有一個金鑰對,私鑰自己留著,公鑰以及其他資訊傳送給 CA,向 CA 提出申請,CA 判明使用者的身份之後,會將這個公鑰和使用者的身份資訊繫結,並且為繫結後的資訊進行簽名(簽名是透過 CA 根證照的私鑰進行的),最後將簽名後的證照發給申請者。
  3. 一個使用者想要鑑定一個證照的真偽,就透過 CA 的公鑰對證照上的數字簽名進行驗證,驗證透過,就認為這個這個證照是有效的。

上面這個流程中有一個重要前提,那就是 CA 受到大家所有人的信任。

然而在實際操作中,我們並不能直接去跟 CA 申請一個數字證照,因為全世界要認證的內容太多了,CA 搞不過來,而且頻繁的找 CA 申請,還有可能導致私鑰洩漏,這可就是一個大的災難了。

那怎麼辦呢?實際操作中,我們可以基於 CA 來構建一個信任鏈。具體來說,步驟是這樣:

  1. 首先我們的手機、筆記本等作業系統中都預裝了 CA 頒發的根證照,他們是所有信任構建的基石,前面松哥已經截圖給大家看了 Windows 中預裝的根證照了。
  2. 假設 CA 簽發了一個證照 A,在這個過程中 CA 稱為 Issuer,A 稱為 Subject,假設 A 是一個受信任的中間證照,已經預裝在我們的作業系統中了。現在由 A 利用它自己的私鑰給某一個網站簽發了一個證照 B。
  3. 現在當我們的電腦需要訪問該網站的時候,該網站就會給我們發來一個證照 B,由於我們的瀏覽器並不知道 B 證照是否合法,但是我們的電腦上已經預裝了 A 證照,我們可以從 A 證照中提取出 A 的公鑰,然後利用 A 的公鑰對 B 證照的簽名進行驗證(因為 B 證照的簽名是 A 的私鑰籤的),如果驗證透過了,就說明 B 是合法的。
  4. 相同的道理,B 也可以繼續簽發 C 證照,C 繼續簽發 D 證照,這樣就形成了一個信任鏈。
  5. 如果服務端的簽名是 D 證照,那麼一般來說,伺服器返回給瀏覽器的就會包含 B、C、D 三個證照(因為 A 證照已經在我們的電腦上了),即使只返回 D 證照,瀏覽器也可以根據 D 書中的資訊,自動下載到 B、C 兩個證照然後進行驗證。

松哥記得以前上大學的時候,在 12306 網站上買火車票,第一次訪問的時候必須要自己先手動安裝一個根證照到系統中,然後才能訪問。這就是因為當時 12306 所使用的證照的簽發機構不被瀏覽器認可,類似於上面的第 3 步,12306 給我發了一個數字證照 B 回來,但是瀏覽器上沒有合適的公鑰對這個 B 證照進行驗證,當我往自己的系統上安裝了 12306 給的證照之後,相當於我的電腦上有了一個證照 A,現在就可以對 B 證照進行驗證了。

總結一下:

  1. CA 是一個權威的機構,是一個發證機關,CA 發出來的證照可以證明一個人或者組織的身份。
  2. 任何人都可以得到 CA 的證照(含公鑰),用以驗證 CA 所簽發的證照。
  3. 每一個數字證照都是由上級證照的私鑰來簽發的,處於最頂層的就是 CA 簽發的根證照了,這個根證照沒有上級證照了,所以這個根證照實際上是由 CA 自己的私鑰來簽發的,這也叫做自簽名,即 Self-Signed。

當我們有了數字簽名之後,就可以解決 3.1 小節最後提出的問題了。服務端將數字簽名發給瀏覽器,瀏覽器利用系統已經內建的公鑰驗籤,確認簽名沒問題,然後就提取出來數字簽名中的公鑰,開始協商對稱加密的私鑰了~

好啦,有了這些知識儲備之後,下篇文章松哥來和大家聊一聊 TLS+gRPC 怎麼玩!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027824/viewspace-2940185/,如需轉載,請註明出處,否則將追究法律責任。

相關文章