公鑰基礎設施和密碼學中的私鑰的角色

Alex Wood發表於2018-09-26

瞭解如何驗證某人所聲稱的身份。

上一篇文章中,我們概述了密碼學並討論了密碼學的核心概念:保密性confidentiality (讓資料保密)、完整性integrity (防止資料被篡改)和身份認證authentication (確認資料來源的身份identity)。由於要在存在各種身份混亂的現實世界中完成身份認證,人們逐漸建立起一個複雜的技術生態體系technological ecosystem,用於證明某人就是其聲稱的那個人。在本文中,我們將大致介紹這些體系是如何工作的。

快速回顧公鑰密碼學及數字簽名

網際網路世界中的身份認證依賴於公鑰密碼學,其中金鑰分為兩部分:擁有者需要保密的私鑰和可以對外公開的公鑰。經過公鑰加密過的資料,只能用對應的私鑰解密。舉個例子,對於希望與記者建立聯絡的舉報人來說,這個特性非常有用。但就本文介紹的內容而言,私鑰更重要的用途是與一個訊息一起建立一個數字簽名digital signature,用於提供完整性和身份認證。

在實際應用中,我們簽名的並不是真實訊息,而是經過密碼學雜湊函式cryptographic hash function處理過的訊息摘要digest。要傳送一個包含原始碼的壓縮檔案,傳送者會對該壓縮檔案的 256 位元長度的 SHA-256 摘要進行簽名,而不是檔案本身進行簽名,然後用明文傳送該壓縮包(和簽名)。接收者會獨立計算收到檔案的 SHA-256 摘要,然後結合該摘要、收到的簽名及傳送者的公鑰,使用簽名驗證演算法進行驗證。驗證過程取決於加密演算法,加密演算法不同,驗證過程也相應不同;而且,很微妙的是簽名驗證漏洞依然層出不窮。如果簽名驗證透過,說明檔案在傳輸過程中沒有被篡改而且來自於傳送者,這是因為只有傳送者擁有建立簽名所需的私鑰。

方案中缺失的環節

上述方案中缺失了一個重要的環節:我們從哪裡獲得傳送者的公鑰?傳送者可以將公鑰與訊息一起傳送,但除了傳送者的自我宣稱,我們無法核驗其身份。假設你是一名銀行櫃員,一名顧客走過來向你說,“你好,我是 Jane Doe,我要取一筆錢”。當你要求其證明身份時,她指著襯衫上貼著的姓名標籤說道,“看,Jane Doe!”。如果我是這個櫃員,我會禮貌的拒絕她的請求。

如果你認識傳送者,你們可以私下見面並彼此交換公鑰。如果你並不認識傳送者,你們可以私下見面,檢查對方的證件,確認真實性後接受對方的公鑰。為提高流程效率,你可以舉辦聚會並邀請一堆人,檢查他們的證件,然後接受他們的公鑰。此外,如果你認識並信任 Jane Doe(儘管她在銀行的表現比較反常),Jane 可以參加聚會,收集大家的公鑰然後交給你。事實上,Jane 可以使用她自己的私鑰對這些公鑰(及對應的身份資訊)進行簽名,進而你可以從一個線上金鑰庫獲取公鑰(及對應的身份資訊)並信任已被 Jane 簽名的那部分。如果一個人的公鑰被很多你信任的人(即使你並不認識他們)簽名,你也可能選擇信任這個人。按照這種方式,你可以建立一個信任網路Web of Trust

但事情也變得更加複雜:我們需要建立一種標準的編碼機制,可以將公鑰和其對應的身份資訊編碼成一個數字捆綁digital bundle,以便我們進一步進行簽名。更準確的說,這類數字捆綁被稱為證書cerificate。我們還需要可以建立、使用和管理這些證書的工具鏈。滿足諸如此類的各種需求的方案構成了公鑰基礎設施public key infrastructure(PKI)。

比信任網路更進一步

你可以用人際關係網類比信任網路。如果人們之間廣泛互信,可以很容易找到(兩個人之間的)一條簡訊任鏈short path of trust:就像一個社交圈。基於 GPG 加密的郵件依賴於信任網路,(理論上)只適用於與少量朋友、家庭或同事進行聯絡的情形。

(LCTT 譯註:作者提到的“簡訊任鏈”應該是暗示“六度空間理論”,即任意兩個陌生人之間所間隔的人一般不會超過 6 個。對 GPG 的唱衰,一方面是因為金鑰管理的複雜性沒有改善,另一方面 Yahoo 和 Google 都提出了更便利的端到端加密方案。)

在實際應用中,信任網路有一些“硬傷significant problems”,主要是在可擴充套件性方面。當網路規模逐漸增大或者人們之間的連線較少時,信任網路就會慢慢失效。如果信任鏈逐漸變長,信任鏈中某人有意或無意誤簽證書的機率也會逐漸增大。如果信任鏈不存在,你不得不自己建立一條信任鏈,與其它組織建立聯絡,驗證它們的金鑰以符合你的要求。考慮下面的場景,你和你的朋友要訪問一個從未使用過的線上商店。你首先需要核驗網站所用的公鑰屬於其對應的公司而不是偽造者,進而建立安全通訊通道,最後完成下訂單操作。核驗公鑰的方法包括去實體店、打電話等,都比較麻煩。這樣會導致線上購物變得不那麼便利(或者說不那麼安全,畢竟很多人會圖省事,不去核驗金鑰)。

如果世界上有那麼幾個格外值得信任的人,他們專門負責核驗和簽發網站證書,情況會怎樣呢?你可以只信任他們,那麼瀏覽網際網路也會變得更加容易。整體來看,這就是當今網際網路的工作方式。那些“格外值得信任的人”就是被稱為證書頒發機構cerificate authoritie(CA)的公司。當網站希望獲得公鑰簽名時,只需向 CA 提交證書籤名請求certificate signing request(CSR)。

CSR 類似於包括公鑰和身份資訊(在本例中,即伺服器的主機名)的存根stub證書,但 CA 並不會直接對 CSR 本身進行簽名。CA 在簽名之前會進行一些驗證。對於一些證書型別(LCTT 譯註:域名證實Domain Validated(DV) 型別),CA 只驗證申請者的確是 CSR 中列出主機名對應域名的控制者(例如透過郵件驗證,讓申請者完成指定的域名解析)。對於另一些證書型別 (LCTT 譯註:連結中提到擴充套件證實Extended Validated(EV)型別,其實還有 OVOrganization Validated 型別),CA 還會檢查相關法律文書,例如公司營業執照等。一旦驗證完成,CA(一般在申請者付費後)會從 CSR 中取出資料(即公鑰和身份資訊),使用 CA 自己的私鑰進行簽名,建立一個(簽名)證書併傳送給申請者。申請者將該證書部署在網站伺服器上,當使用者使用 HTTPS (或其它基於 TLS 加密的協議)與伺服器通訊時,該證書被分發給使用者。

當使用者訪問該網站時,瀏覽器獲取該證書,接著檢查證書中的主機名是否與當前正在連線的網站一致(下文會詳細說明),核驗 CA 簽名有效性。如果其中一步驗證不透過,瀏覽器會給出安全警告並切斷與網站的連線。反之,如果驗證透過,瀏覽器會使用證書中的公鑰來核驗該伺服器傳送的簽名資訊,確認該伺服器持有該證書的私鑰。有幾種演算法用於協商後續通訊用到的共享金鑰shared secret key,其中一種也用到了伺服器傳送的簽名資訊。金鑰交換key exchange演算法不在本文的討論範圍,可以參考這個影片,其中仔細說明了一種金鑰交換演算法。

建立信任

你可能會問,“如果 CA 使用其私鑰對證書進行簽名,也就意味著我們需要使用 CA 的公鑰驗證證書。那麼 CA 的公鑰從何而來,誰對其進行簽名呢?” 答案是 CA 對自己簽名!可以使用證書公鑰對應的私鑰,對證書本身進行簽名!這類簽名證書被稱為是自簽名的self-signed;在 PKI 體系下,這意味著對你說“相信我”。(為了表達方便,人們通常說用證書進行了簽名,雖然真正用於簽名的私鑰並不在證書中。)

透過遵守瀏覽器作業系統供應商建立的規則,CA 表明自己足夠可靠並尋求加入到瀏覽器或作業系統預裝的一組自簽名證書中。這些證書被稱為“信任錨trust anchor”或 CA 根證書root CA certificate,被儲存在根證書區,我們約定implicitly信任該區域內的證書。

CA 也可以簽發一種特殊的證書,該證書自身可以作為 CA。在這種情況下,它們可以生成一個證書鏈。要核驗證書鏈,需要從“信任錨”(也就是 CA 根證書)開始,使用當前證書的公鑰核驗下一層證書的簽名(或其它一些資訊)。按照這個方式依次核驗下一層證書,直到證書鏈底部。如果整個核驗過程沒有問題,信任鏈也建立完成。當向 CA 付費為網站簽發證書時,實際購買的是將證書放置在證書鏈下的權利。CA 將賣出的證書標記為“不可簽發子證書”,這樣它們可以在適當的長度終止信任鏈(防止其繼續向下擴充套件)。

為何要使用長度超過 2 的信任鏈呢?畢竟網站的證書可以直接被 CA 根證書籤名。在實際應用中,很多因素促使 CA 建立中間 CA 證書intermediate CA certificate,最主要是為了方便。由於價值連城,CA 根證書對應的私鑰通常被存放在特定的裝置中,一種需要多人解鎖的硬體安全模組hardware security module(HSM),該模組完全離線並被保管在配備監控和報警裝置的地下室中。

CA/瀏覽器論壇CAB Forum, CA/Browser Forum負責管理 CA,要求任何與 CA 根證書(LCTT 譯註:就像前文提到的那樣,這裡是指對應的私鑰)相關的操作必須由人工完成。設想一下,如果每個證書請求都需要員工將請求內容複製到保密介質中、進入地下室、與同事一起解鎖 HSM、(使用 CA 根證書對應的私鑰)簽名證書,最後將簽名證書從保密介質中複製出來;那麼每天為大量網站簽發證書是相當繁重乏味的工作。因此,CA 建立內部使用的中間 CA,用於證書籤發自動化。

如果想檢視證書鏈,可以在 Firefox 中點選位址列的鎖型圖示,接著開啟頁面資訊,然後點選“安全”皮膚中的“檢視證書”按鈕。在本文寫作時,opensource.com 使用的證書鏈如下:

DigiCert High Assurance EV Root CA
    DigiCert SHA2 High Assurance Server CA
        opensource.com

中間人

我之前提到,瀏覽器需要核驗證書中的主機名與已經建立連線的主機名一致。為什麼需要這一步呢?要回答這個問題,需要了解所謂的中間人攻擊man-in-the-middle, MIMT。有一類網路攻擊可以讓攻擊者將自己置身於客戶端和服務端中間,冒充客戶端與服務端連線,同時冒充服務端與客戶端連線。如果網路流量是透過 HTTPS 傳輸的,加密的流量無法被竊聽。此時,攻擊者會建立一個代理,接收來自受害者的 HTTPS 連線,解密資訊後構建一個新的 HTTPS 連線到原始目的地(即服務端)。為了建立假冒的 HTTPS 連線,代理必須返回一個攻擊者具有對應私鑰的證書。攻擊者可以生成自簽名證書,但受害者的瀏覽器並不會信任該證書,因為它並不是根證書庫中的 CA 根證書籤發的。換一個方法,攻擊者使用一個受信任 CA 簽發但主機名對應其自有域名的證書,結果會怎樣呢?

再回到銀行的那個例子,我們是銀行櫃員,一位男性顧客進入銀行要求從 Jane Doe 的賬戶上取錢。當被要求提供身份證明時,他給出了 Joe Smith 的有效駕駛執照。如果這個交易可以完成,我們無疑會被銀行開除。類似的,如果檢測到證書中的主機名與連線對應的主機名不一致,瀏覽器會給出類似“連線不安全”的警告和檢視更多內容的選項。在 Firefox 中,這類錯誤被標記為 SSL_ERROR_BAD_CERT_DOMAIN

我希望你閱讀完本文起碼記住這一點:如果看到這類警告,不要無視它們!它們出現意味著,或者該網站配置存在嚴重問題(不推薦訪問),或者你已經是中間人攻擊的潛在受害者。

總結

雖然本文只觸及了 PKI 世界的一些皮毛,我希望我已經為你展示了便於後續探索的大致藍圖。密碼學和 PKI 是美與複雜性的結合體。越深入研究,越能發現更多的美和複雜性,就像分形那樣。


via: https://opensource.com/article/18/7/private-keys

作者:Alex Wood 選題:lujun9972 譯者:pinewall 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

公鑰基礎設施和密碼學中的私鑰的角色

相關文章