Kerberos

**Kerberos**（/ˈkərbərəs/）是一種電腦網路授權協定，用來在非安全網路中，對個人通信以安全的手段進行身分認證。這個詞又指麻省理工學院為這個協定開發的一套電腦軟體。軟體設計上採用客戶端 / 伺服器結構，並且能夠進行相互認證，即客戶端和伺服器端均可對對方進行身分認證。可以用於防止竊聽、防止重放攻擊、保護資料完整性等場合，是一種應用對稱金鑰體制進行金鑰管理的系統。Kerberos 的擴充產品也使用公開金鑰加密方法進行認證。

當有 N 個人使用該系統時，為確保在任意兩個人之間進行秘密對話，系統至少儲存有它與每個人的共享金鑰，所需的最少對談金鑰數為 N 個。

## 歷史

麻省理工學院研發 Kerberos 協定來保護雅典娜工程（Project Athena）提供的網路伺服器。這個協定以希臘神話中的人物 Kerberos（或者 Cerberus）命名，他在希臘神話中是 Hades 的一條兇猛的三頭保衛神犬。目前該協定存在一些版本，版本 1-3 都只有麻省理工內部發行。

Kerberos 版本 4 的主要設計者 Steve Miller 和 Clifford Neuman，在 1980 年代後期發布這個版本。這個版本主要針對雅典娜工程。版本 5 由 John Kohl 和 Clifford Neuman 設計，在 1993 年作為 RFC 1510 頒布（在 2005 年由 RFC 4120 取代），目的在於克服版本 4 的局限性和安全問題。

麻省理工在著作權許可的情況下，製作一個 Kerberos 的免費實現工具，這種情況類似於 BSD。在 2007 年，麻省理工組成一個 Kerberos 協會，以此推動 Kerberos 的持續發展。

因為使用資料加密標準（DES）加密演算法（用 56 bit 的金鑰），美國出口管制當局把 Kerberos 歸類為軍需品，並禁止其出口。一個非美國設計的 Kerberos 版本 4 的實現工具 KTH-KRB 由瑞典皇家工學院研製，它使得這套系統在美國更改密碼出口管理條例前（大約是在 2000 年），在美國境外就可以使用。瑞典的實現工具基於一個叫做 eBones 的版本，而 eBones 基於麻省理工對外發行的基於 Kerberos 版本 4 的修補程式 9 的 Bones（跳過加密公式和對它們的函式呼叫）。這些在一定程度上決定 Kerberos 為什麼沒有被叫做 eBones 版。Kerberos 版本 5 的實現工具，Heimdal，基本上也是由發布 KTH-KRB 的同一組人發布。

在 2005 年，網際網路工程任務組（IETF）Kerberos 工作小組更新了規範，更新包括：

* "Kerberos 5 加密和校驗和規範"（RFC 3961）。
* "Kerberos 5 進階加密標準（AES）加密"（RFC 3962）。
* "Kerberos 網路認證服務（版本 5）"（RFC 4120）—Kerberos 版本 5 規範的新版本。這個版本廢棄早先的 RFC 1510，用更細化和明確的解釋說明協定的一些細節和使用方法。
* "Kerberos 5 通用安全服務應用程式介面（GSS-API）機制：版本 2"（RFC 4121）— 通用安全服務應用程式介面（GSS-API）規範的新版本。

Windows 2000 和後續的作業系統使用 Kerberos 為其預設認證方法。RFC 3244 "微軟 Windows 2000 Kerberos 變更密碼與設定密碼協定" 記錄整理一些微軟對 Kerberos 協定軟體套件的添加。RFC 4757 記錄整理微軟對 RC4 密碼的使用。雖然微軟使用 Kerberos 協定，卻並沒有用麻省理工的軟體。

蘋果的 Mac OS X 也使用 Kerberos 的客戶和伺服器版本。Red Hat Enterprise Linux 4 和後續的作業系統使用 Kerberos 的客戶和伺服器版本。

## 基本描述

Kerberos 使用 Needham-Schroeder 協定作為它的基礎。它使用一個由兩個獨立的邏輯部分：認證伺服器和票據授權伺服器組成的 "可信賴的第三方"，術語稱為金鑰分發中心（KDC）。Kerberos 工作在用於證明使用者身分的 "票據" 的基礎上。

KDC 持有一個金鑰資料庫；每個網路實體 —— 無論是客戶還是伺服器 —— 共享一套只有他自己和 KDC 知道的金鑰。金鑰的內容用於證明實體的身分。對於兩個實體間的通信，KDC 產生一個對談金鑰，用來加密他們之間的相互資訊。

## 協定內容

協定的安全主要依賴於參加者對時間的鬆散同步和短周期的叫做 Kerberos 票據的認證聲明。
下面是對這個協定的一個簡化描述，將使用以下縮寫：

* AS（Authentication Server）= 認證伺服器
* KDC（Key Distribution Center）= 金鑰分發中心
* TGT（Ticket Granting Ticket）= 票據授權票據，票據的票據
* TGS（Ticket Granting Server）= 票據授權伺服器
* SS（Service Server）= 特定服務提供端

客戶端使用者傳送自己的使用者名稱到 KDC 伺服器以向 AS 服務進行認證。KDC 伺服器會生成相應的 TGT 票據，打上時間戳，在本地資料庫中尋找該使用者的密碼，並用該密碼對 TGT 進行加密，將結果發還給客戶端使用者。該操作僅在使用者登入或者 kinit 申請的時候進行。
客戶端收到該資訊，並使用自己的密碼進行解密之後，就能得到 TGT 票據了。這個 TGT 會在一段時間之後失效，也有一些程式（session manager）能在使用者登陸期間進行自動更新。
當客戶端使用者需要使用一些特定服務（Kerberos 術語中用「principal」表示）時，該客戶端就傳送 TGT 到 KDC 伺服器中的 TGS 服務。當該使用者的 TGT 驗證通過並且其有權存取所申請的服務時，TGS 服務會生成一個該服務所對應的 ticket 和 session key，並行還給客戶端。客戶端將服務請求與該 ticket 一併傳送給相應的伺服器端即可。具體的流程請看下面的描述。

其在網路通訊協定中屬於顯示層。

簡單地說，使用者先用共享金鑰從某認證伺服器得到一個身分證明。隨後，使用者使用這個身分證明與 SS 通信，而不使用共享金鑰。

## 具體流程

（注意：此流程使用了對稱加密；此流程發生在某**一個** Kerberos **領域**中；小寫字母 c,d,e,g 是客戶端發出的訊息，大寫字母 A,B,E,F,H 是各個伺服器發回的訊息。）

首先，使用者使用客戶端（使用者自己的機器）上的程式進行登入：

1. 使用者輸入使用者 ID 和密碼到客戶端。
2. 客戶端程式執行一個單向函式（大多數為雜湊）把密碼轉換成金鑰，這個就是客戶端（使用者）的「使用者金鑰」(user's secret key)。

隨後，**客戶端認證**（客戶端 (Client) 從認證伺服器 (AS) 取得票據授權票據（TGT））：

1. 客戶端向 AS 傳送 1 條明文訊息，申請基於該使用者所應享有的服務，例如「使用者 Sunny 想請求服務」（Sunny 是使用者 ID）。（注意：使用者不向 AS 傳送「使用者金鑰」，也不傳送密碼）該 AS 能夠從本地資料庫中查詢到該申請使用者的密碼，並通過相同途徑轉換成相同的「使用者金鑰」。
2. AS 檢查該使用者 ID 是否在於本地資料庫中，如果使用者存在則返回 2 條訊息：
  * 訊息 A：**客戶端 / TGS 對談金鑰 (Client/TGS Session Key)**（該對談金鑰用在將來客戶端與 TGS 的通信（對談）上），通過「使用者金鑰」進行加密
  * 訊息 B：**TGT**（TGT 包括：訊息 A 中的「客戶端 / TGS 對談金鑰」，使用者 ID，使用者網址，TGT 有效期），通過「TGS 金鑰」(TGS's secret key) 進行加密
3. 一旦客戶端收到訊息 A 和訊息 B，客戶端首先嘗試用自己的「使用者金鑰」解密訊息 A，如果使用者輸入的密碼與 AS 資料庫中的密碼不符，則不能成功解密訊息 A。輸入正確的密碼並通過隨之生成的「使用者金鑰」才能解密訊息 A，從而得到「客戶端 / TGS 對談金鑰」。（注意：客戶端不能解密訊息 B，因為 B 是用「TGS 金鑰」加密的）。擁有了「客戶端 / TGS 對談金鑰」，客戶端就足以通過 TGS 進行認證了。

然後，**服務授權**（客戶端從 TGS 取得票據 (client-to-server ticket)）：

1. 當客戶端需要申請特定服務時，其向 TGS 傳送以下 2 條訊息：
  * 訊息 c：即訊息 B 的內容（「TGS 金鑰」加密後的 TGT），和想取得的服務的服務 ID（注意：不是使用者 ID）
  * 訊息 d：**認證符 (Authenticator)**（Authenticator 包括：使用者 ID，時間戳），通過「客戶端 / TGS 對談金鑰」進行加密
2. 收到訊息 c 和訊息 d 後，TGS 首先檢查 KDC 資料庫中是否存在所需的服務，尋找到之後，TGS 用自己的「TGS 金鑰」解密訊息 c 中的訊息 B（也就是 TGT），從而得到之前生成的「客戶端 / TGS 對談金鑰」。TGS 再用這個對談金鑰解密訊息 d 得到包含使用者 ID 和時間戳的 Authenticator，並對 TGT 和 Authenticator 進行驗證，驗證通過之後返回 2 條訊息：
  * 訊息 E：**客戶端 - 伺服器票據 (client-to-server ticket)**（該票據包括：「客戶端 / SS 對談金鑰」(Client/Server Session Key），使用者 ID，使用者網址，有效期），通過提供該服務的「伺服器金鑰」(service's secret key)**進行加密**
  * 訊息 F：**客戶端 / SS 對談金鑰 (Client/Server Session Key)**（該對談金鑰用在將來客戶端與 SS 的通信（對談）上），通過「客戶端 / TGS 對談金鑰」進行加密
3. 客戶端收到這些訊息後，用「客戶端 / TGS 對談金鑰」解密訊息 F，得到「客戶端 / SS 對談金鑰」。（注意：客戶端不能解密訊息 E，因為 E 是用「伺服器金鑰」加密的）。

最後，**服務請求**（客戶端從 SS 取得服務）：

1. 獲得「客戶端 / SS 對談金鑰」之後，客戶端就能夠使用伺服器提供的服務了。客戶端向指定 SS 發出 2 條訊息：
  * 訊息 e：即上一步中的訊息 E「客戶端 - 伺服器票據」，已通過「伺服器金鑰」進行加密
  * 訊息 g：新的 **Authenticator**（包括：使用者 ID，時間戳），通過「客戶端 / SS 對談金鑰」進行加密
2. SS 用自己的「伺服器金鑰」解密訊息 e 從而得到 TGS 提供的「客戶端 / SS 對談金鑰」。再用這個對談金鑰解密訊息 g 得到 Authenticator，（同 TGS 一樣）對票據和 Authenticator 進行驗證，驗證通過則返回 1 條訊息（確認函：確證身分真實，樂於提供服務）：
  * 訊息 H：**新時間戳**（新時間戳是：客戶端傳送的時間戳加 1，v5 已經取消這一做法），通過「客戶端 / SS 對談金鑰」進行加密
3. 客戶端通過「客戶端 / SS 對談金鑰」解密訊息 H，得到新時間戳並驗證其是否正確。驗證通過的話則客戶端可以信賴 SS，並向 SS 傳送服務請求。
4. SS 向客戶端提供相應的服務。

## 缺陷

* 單點故障：它需要中心伺服器的持續回應。當 Kerberos 服務宕機時，沒有人可以連接到伺服器。這個缺陷可以通過使用複合 Kerberos 伺服器和缺陷認證機制彌補。
* Kerberos 要求參與通信的主機的時鐘同步。票據具有一定有效期，因此，如果主機的時鐘與 Kerberos 伺服器的時鐘不同步，認證會失敗。預設設定要求時鐘的時間相差不超過 10 分鐘。在實踐中，通常用網路時間協定後台程式來保持主機時鐘同步。
* 管理協定並沒有標準化，在伺服器實現工具中有一些差別。RFC 3244 描述了密碼更改。
* 因為所有使用者使用的金鑰都儲存於中心伺服器中，危及伺服器的安全的行為將危及所有使用者的金鑰。
* 一個危險客戶機將危及使用者密碼。

## 參考資料

## 延伸閱讀

## 外部連結

* Kerberos Consortium （頁面存檔備份，存於網際網路檔案館）
* Kerberos page（頁面存檔備份，存於網際網路檔案館） at MIT website
* Kerberos Working Group at IETF website
* Kerberos Sequence Diagram （頁面存檔備份，存於網際網路檔案館）