前言

當我們想把伺服器以 HTTPS 對外公開時,一定會遇到的就是「憑證」。這就是瀏覽器會顯示鎖頭圖示的那套機制,但能夠按步驟說清楚「為什麼需要它」「是誰發行的」「誰為了什麼而使用它」的人,其實意外地少。

本文將從憑證究竟是為了要解決什麼問題這個基礎開始,一直到實際上是如何驗證的這些稍微深入的部分,一併整理說明。

為什麼需要憑證

先從「會遇到的麻煩」來思考。當網際網路上的瀏覽器與伺服器進行通訊時,可能會發生以下兩個問題。

  • 冒名頂替:就算有一個長得跟真的一模一樣的假網站,自稱「我是正版伺服器」,瀏覽器端也沒有辦法分辨
  • 竊聽・竄改:未加密的通訊,可能在途中經過的路徑(例如公共 Wi-Fi)被偷看或被改寫

憑證就是用來同時解決這兩個問題的機制。它由第三方保證「這台伺服器確實是那個網域的擁有者在營運」,並且負責安全地傳遞「用於加密通訊的金鑰」。

什麼是憑證

憑證(SSL/TLS 憑證) 是一種用來證明伺服器身分的電子檔案。技術上它是依照 X.509 規格的資料格式,主要包含以下資訊。

項目內容主體(Subject)表示這張憑證屬於誰(哪個網域)的資訊公開金鑰(Public Key)用於加密通訊的一方金鑰(後述)簽發者(Issuer)簽發這張憑證的憑證機構資訊有效期限這張憑證從何時到何時有效數位簽章簽發者保證「這個內容是真的」的簽章

概念上可以把它想成一張寫有「網域名稱」「公開金鑰」「有效期限」等資訊的身分證,再加上由發行單位蓋了章(簽章)的版本,會比較好理解。

誰來發行:憑證機構(CA)

憑證不能只靠自己宣稱就算數,還需要第三方背書。負責提供這種背書的組織就是憑證機構(CA:Certificate Authority)

常見的憑證機構除了 DigiCert、Sectigo 等商業 CA 之外,也有像 Let's Encrypt 這種免費且可自動發行憑證的非營利憑證機構。近年來在伺服器建置自動化的趨勢下,像 Let's Encrypt 這類具備自動發行機制的 CA 已經被廣泛使用。

憑證機構如何確認網域持有者

在憑證機構發行憑證之前,會先確認申請者是否真的在管理該網域(網域驗證)。包含 Let's Encrypt 在內的多數自動發行機制,都是根據 ACME 協定,透過以下這類「Challenge」來確認。

挑戰方式確認方法特點HTTP-01將指定檔案放到 http://網域/.well-known/acme-challenge/ 路徑下,並確認憑證機構是否能成功取得簡單、容易自動化,但不能用於發行萬用憑證DNS-01在網域的 DNS TXT 記錄(_acme-challenge.網域)中設定指定的值,並讓憑證機構查詢 DNS 進行確認可以發行萬用憑證,但需要 DNS 端支援 API

例如想取得 *.example.com 這種萬用憑證(可涵蓋該網域下任意子網域的憑證),就必須使用 DNS-01 Challenge。透過 DNS 供應商的 API 自動新增 TXT 記錄,讓憑證機構確認後,發行就完成了。

信任鏈(Chain of Trust)

憑證機構並不是單一層級,而通常會是「根憑證」與「中繼憑證」組成的階層結構。

  • 根憑證:由憑證機構自己為自己的身分做保證(自我簽署),位於信任最上層的憑證。預先內建於作業系統或瀏覽器中
  • 中繼憑證:由根憑證簽署,用來實際替伺服器憑證簽章的憑證
  • 伺服器憑證(Leaf 憑證):實際安裝到伺服器上的、每個網域各自對應的憑證

瀏覽器會依序沿著「伺服器憑證 → 中繼憑證 → 根憑證」的簽章鏈向上驗證,最後如果能追溯到預先信任的根憑證,就會判定「這張伺服器憑證是可信的」。這一整套連結關係稱為 信任鏈(Chain of Trust)

誰在使用

與憑證相關的角色大致可分成兩類。

  • 伺服器營運者:向憑證機構申請、取得憑證,並安裝到自己的伺服器上
  • 用戶端(瀏覽器等):驗證收到的憑證是否可信

瀏覽器和作業系統中,預先內建了許多受信任的憑證機構根憑證(信任存放區,Trust Store)。只要是這份清單內的 CA 所簽發的憑證,使用者通常不需要特別注意,就會被視為「安全連線」。

實際上如何使用:TLS 握手流程

憑證是在 HTTPS 通訊一開始的 TLS 握手 流程中使用的。大致流程如下。

  1. 用戶端(瀏覽器)向伺服器發出連線請求(Client Hello)
  2. 伺服器出示自己的憑證(Server Hello + Certificate)
  3. 用戶端依照信任鏈驗證該憑證(簽章是否正確、是否在有效期限內、網域名稱是否一致)
  4. 驗證成功後,會利用憑證中的公開金鑰,安全地交換接下來要使用的加密金鑰(共用金鑰)資訊
  5. 之後的通訊就會使用這個共用金鑰進行加密

這裡出現的「公開金鑰」所對應的,就是只有伺服器端持有的「私密金鑰」。用憑證中的公開金鑰加密的內容,只有持有對應私密金鑰的伺服器才能解密。透過這個機制,即使途中遭到竊聽,內容也不容易被讀取。

「有沒有加密」與「是不是冒名頂替」是兩件不同的事。憑證的角色就是同時保證這兩件事。單純只做加密的話,自我簽署憑證也可以,但那樣無法由第三方證明「這是正版伺服器」。

憑證的種類

依照驗證嚴謹程度,憑證可分為幾種類型。

種類縮寫驗證內容網域驗證DV(Domain Validation)只確認網域的管理權限。最簡單的形式,Let's Encrypt 也是這種組織驗證OV(Organization Validation)除了網域之外,也會確認營運組織的實體存在性延伸驗證EV(Extended Validation)最嚴格的審查。過去曾在瀏覽器位址列顯示組織名稱,但現在主要瀏覽器幾乎已不再有明顯的顯示差異

此外,從發行來源的角度來看,還有不透過正式憑證機構、由自己簽署的自我簽署憑證。它可用於公司內部測試等用途,但因為不在瀏覽器的信任存放區中,所以瀏覽器會顯示「這個連線未受到保護」之類的警告。

實務上的重點

  • 萬用憑證的重複利用:只要先發行一張像 *.example.com 這樣的萬用憑證,就不需要每新增一個子網域就個別申請,維運會更簡單
  • 憑證切換步驟:如果多個對外入口(例如反向代理的主機設定)共用同一張憑證,應該在所有參照都切換到新憑證之後,再刪除舊憑證。若在切換途中就刪掉舊憑證,相關設定重新載入可能會失敗,甚至連不相關的對外服務也會一起無法存取
  • 到期警告:憑證一定有有效期限,而 Let's Encrypt 的憑證只有 90 天,期限相對較短。如果沒有建立自動更新機制(例如用 cron 定期執行),很容易在不知不覺中過期
  • 自我簽署憑證的警告:在開發環境使用自我簽署憑證時,瀏覽器出現警告不是異常,而是符合設計的行為。因為它沒有經過正式憑證機構簽發,瀏覽器出現這種反應是理所當然的

總結

疑問回答什麼是憑證用來保證伺服器身分,並安全傳遞加密通訊金鑰的電子證明為什麼需要用來防止冒名頂替,以及防止竊聽・竄改誰來發行憑證機構(CA)。像 Let's Encrypt 這類也有免費、自動發行的 CA如何確認透過 HTTP-01/DNS-01 等 Challenge 確認網域管理權,並以根憑證的信任鏈驗證可信度誰在使用伺服器營運者(取得・安裝)與用戶端(驗證)雙方

參考


原文出處:https://qiita.com/mame_hiro416/items/dc7a18f58eb5a2c8a6e7


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝8   💬2   ❤️4
237
🥈
我愛JS
📝2   💬6   ❤️3
110
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登