Kerberos

Kerberos（ˈ）是一種電腦網絡授權協議，用來在非安全網路中，對個人通信以安全的手段進行身份認證。這個詞又指麻省理工學院為這個協議開發的一套電腦軟體。軟體設計上採用客戶端/伺服器結構，並且能夠進行相互認證，即客戶端和伺服器端均可對對方進行身份認證。可以用於防止竊聽、防止重放攻擊、保護數據完整性等場合，是一種應用對稱密鑰體制進行密鑰管理的系統。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是各個伺服器發回的消息。）

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

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

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

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

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

- 當客戶端需要申請特定服務時，其向TGS發送以下2條消息：
- 消息c：即消息B的內容（「TGS密鑰」加密後的TGT），和想獲取的服務的服務ID（注意：不是使用者ID）
- 消息d：認證符(Authenticator)（Authenticator包括：使用者ID，時間戳），通過「客戶端/TGS會話密鑰」進行加密
- 收到消息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會話密鑰」進行加密
- 客戶端收到這些消息後，用「客戶端/TGS會話密鑰」解密消息F，得到「客戶端/SS會話密鑰」。（注意：客戶端不能解密消息E，因為E是用「伺服器密鑰」加密的）。

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

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

## 缺陷

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

## 外部連結

- Kerberos Consortium
- Kerberos page at MIT website
- Kerberos Working Group at IETF website
- Kerberos Sequence Diagram