如何構建私有公鑰基礎設施

jopen 9年前發布 | 7K 次閱讀 公鑰

 

相當復雜的現代Web服務大多數都不是由單體應用提供。為了處理復制的操作,應用程序通常被分解成許多服務,分別處理業務邏輯或數據存儲的不同部分。這些服務可能部署在不同的機器甚或是不同的數據中心。在 CloudFlare ,隨著服務的增加,應用程序之間安全通信的需求也在增長。他們需要一種簡單、可維護的方法來確保CloudFlare內部服務之間的所有通信都始終處于安 全保護之下。因此,他們基于已知且可靠的協議構建了一個這樣的系統。該系統基于一個“公鑰基礎設施(public key infrastructure,縮寫為PKI)”,使用了內部托管的認證中心(CA)。近日,CloudFlare系統工程師Nick Sullivan 介紹 了私有PKI構建過程和內部使用方式。

他們的方法是所有的新服務都使用一種同加密協議——傳輸層安全(TLS)協議——保護服務間通信。這是一種很自然的選擇:HTTPS中的“S”就是 TLS,它是Web加密的基礎。而且,現代Web服務和API均以TLS作為應用層加密事實上的標準。它可以與RESTful服務無縫集成,并獲得了 Kyoto TycoonPostgreSQL 和Go標準庫的支持。另外,Nick在先前發表的一篇 文章 中討論過,未經身份驗證的加密可能遭受 中間人攻擊 。也就是說,加密但不做身份驗證無法在傳輸中保護數據。為了連接安全,每個連接方都必須向另一方提供身份標識。公鑰加密技術提供了許多種信任機制,包括 PGP 的“信任網絡( web of trust )”和HTTPS的公鑰基礎設施模型。由于更易于使用和部署,他們選擇了PKI,由它和TLS一起提供可信任的通信。

PKI借助數字證書和公鑰加密技術提供可信任的網絡身份。通常,證書就是一個包含如下身份信息的文件:

  • 證書所有組織的信息
  • 公鑰
  • 證書頒發組織的信息
  • 證書頒發組織授予的權限,如證書有效期、適用的主機名、用途等
  • 使用證書頒發組織私鑰創建的數字簽名

如何構建私有公鑰基礎設施

每個公鑰都有一個對應的私鑰,后者在證書所有者的管控之下,可以用于對數據進行數字簽名,驗證器可以使用證書中的公鑰對數據進行驗證。如果證書本 身包含第三方認證中心的數字簽名,那么只要驗證器信任該第三方,就可以確保證書是合法的。有時候,證書是由中介認證中心簽名,而中介認證中心的證書又是由 不同的認證中心簽名。在這種情況下,證書驗證器會沿著這條鏈一直找到它信任的證書。對于認證中心而言,信任鏈模型非常有用,它允許我們將根證書的私鑰離線 存儲,只為中介證書簽名。中介認證中心的正式存在時間較短, 可以為端點證書簽名。

如何構建私有公鑰基礎設施

這與Web上HTTPS使用的系統相同。但對于不需要通過瀏覽器訪問的內部服務,就沒有必要通過第三方認證中心。也就是說,受信任證書不必由 GlobalsignComodoVerisign 或其它認證中心頒發,它們可以由你自己的CA頒發。

創建自己的認證中心(CA)

為了創建一個可以輕松獲取和操作證書的內部認證中心,他們使用了自己開源的PKI工具箱 CFSSL 。該工具具有運行一個認證中心所需的全部功能。雖然CFSSL是為運行內部CA而創建,但它足夠健壯,可以用于公開的受信任CA。實際上, Let’s Encrypt 項目就使用CFSSL作為CA基礎設施的一個核心部件。

運行認證中心需要一個CA證書和相應的私鑰。后者是極其敏感的數據。任何知道私鑰的人都可以充當CA頒發證書。因此,私鑰的保護至關重要。CFSSL支持以下三種私鑰保護模式:

接下來,我們將沿著Nick的思路看下如何使用純文本私鑰快速配置一個內部CA。

生成CA證書和私鑰

創建一個包含如下組織基本信息的文件 csr_ca.json

{ "CN": "My Awesome CA", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "San Francisco", "O": "My Awesome Company", "OU": "CA Services", "ST": "California" } ] } 

執行下面的命令:

$ cfssl gencert -initca csr_ca.json | cfssljson -bare ca 

該命令會生成運行CA所必需的文件 ca-key.pem (私鑰)和 ca.pem (證書),還會生成 ca.csr (證書簽名請求),用于交叉簽名或重新簽名。

配置證書生成策略,并啟動CA服務

配置證書生成策略,讓CA軟件知道頒發什么樣的證書。下面是一個簡單的示例:

config_ca.json { "signing": { "default": { "auth_key": "key1", "expiry": "8760h", "usages": [ "signing", "key encipherment", "server auth" ] } }, "auth_keys": { "key1": { "key": <16 byte hex API key here>, "type": "standard" } } } 

該策略指定了證書有效期(1年)、用途(服務器驗證等)以及一個隨機生成的私有驗證密鑰。該密鑰可以防止未經授權的機構請求證書。

執行下面的命令,啟動CA服務:

$ cfssl serve -ca-key ca-key.pem -ca ca.pem -config config_ca.json 

證書生成與簽名

截止目前,基于CFSSL的CA已經配置完成,不妨假設它運行在服務器“ca1.mysite.com”上。該CA如何頒發證書呢?CFSSL提供了兩個命令: gencertsigngencert 將自動處理整個證書生成過程。該過程需要兩個文件,一個告訴CFSSL本地客戶端CA的位置以及如何驗證請求,另一個為CSR配置信息,用于填充CSR。下面是為一個為數據庫服務db1.mysite.com創建證書的例子:

config_client.json

{ "signing": { "default": { "auth_key": "key1", "remote": "caserver" } }, "auth_keys": { "key1": { "key": <16 byte hex API key here>, "type": "standard" } }, "remotes": { "caserver": “ca1.mysite.com:8888" } } 

csr_client.json

{ "hosts": [ "db1.mysite.com" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "San Francisco", "O": “My Awesome Company", "OU": “Data Services", "ST": "California" } ] } 

有了這兩個文件就可以使用下面的命令為數據庫服務器db1.mysite.com創建證書了:

$ cfssl gencert -config config_client.json csr_client.json | cfssljson -bare db 

前面已經提到過,該命令會生成三個文件,其中 db-key.pemdb.pemdb.csr ,其中 db.csr 可以再次提交給CA,使用 sign 命令重新簽名:

$ cfssl sign -config config_client.json db.csr | cfssljson -bare db-new 

該命令會生成新證書 db-new.pem 。這兩個命令使私有PKI搭建變得非常容易和便利。

使用PKI

為應用程序生成證書和密鑰有兩種方式:集中式和分布式。前者是指預先配置好一臺中央服務器,由它創建所有的證書并發送給每臺應用程序服務器;后者 是指由應用服務器創建自己的私鑰,并向驗證中心發送證書申請。按照Nick的說法,在第一種方式中,中央服務器管理復雜,而且向應用服務器傳輸私鑰會引入 不必要的風險。相比之下,第二種方式可以按需申請證書,非常易于擴展。

確立服務之間的信任關系

瀏覽器通過檢查證書簽名以及根據“主題備用名稱(Subject Alternative Names,縮寫為SAN)”列表檢查主機名來驗證網站證書。這種顯式檢查有用,但可能會 出現不正常情況 。另一種使服務相互信任的方式是基于單服務CA的隱式檢查,其思想很簡單:每組服務使用不同的CA。比如,由數據庫CA頒發所有數據庫的證書,由API服務器CA頒發所有API服務器的證書。

如何構建私有公鑰基礎設施

當這些服務彼此間使用相互TLS驗證進行通信時,將信任關系配置為:

  • API服務器只信任DB CA
  • DB服務器只信任API CA

配置完成后,A類型的服務將只能和B類型的服務通信。下圖描述了兩個應用程序如何使用相互TLS驗證確立相互信任關系:

如何構建私有公鑰基礎設施

如上圖,API 服務器信任DB CA(紅色)。因此,它只接受由DB CA(帶紅絲帶)簽名的證書。反之,數據庫服務器只接受由API CA(帶橙絲帶)簽名的證書。為了建立一個受信任連接,雙方互相發送一個“密鑰共享(key share)”,并用它們的私鑰簽名。密鑰共享合并到一起創建一個會話密鑰,會話雙方用它加密數據。

將PKI用于遠程服務

內部PKI非常靈活,可以用于向集成到PKI所在網絡的第三方發放證書。例如,CloudFlare有一個名為 Railgun 的服務,可以用于優化CloudFlare與源服務器的連接。Railgun與CloudFlare之間的通信就是使用CloudFlare認證中心頒發的證書進行加密與身份驗證。這可以確保數據傳輸安全。

如何構建私有公鑰基礎設施

小結

實現應用程序層數據安全是確保分布式系統架構安全的重要一步,但只有在有一個強大的PKI時才能實現真正有效的安全防護。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!