Kerberos的元件和術語(翻譯和註解)

devos發表於2016-04-30

之所以要翻譯這篇文章,是因為提到了一些通常於對Kerberos協議簡介性質的文章所沒有提到的細節,而這些細節對於理解Kerberos的工作原理,以及Kerberos協議實現的使用都是很有必要的。

1.3 元件和術語的定義

這一節給了關於物件和術語的定義,對於這些的瞭解對於接下來關於Kerberos協議的描述是非常關鍵的。因為有些定義是基於其它定義的,所以我會盡量嘗試按照順序來講解它們,以使得先給出它們的含義再給出定義(譯註:這裡原文有些怪怪的,不過大概意思就是按照術語出現的先後來解釋它們)。儘管如此,把這一節多讀兩篇來完全理解這些術語也是有必要的。

 

1.3.1 Realm

"realm"這個術語表示一個認證管理域(譯註,意思是:屬於同一個域的使用者使用同樣的認證方案。這個可以見照kdc.conf來理解,在kdc.conf中,很多配置 項是每個realm不同的,比如database的位置,ACL設定 )realm用來建立認證的邊界,在屬於一個認證服務的邊界內,這個認證服務才有權利認證一個使用者,主機或者服務。但這並不意味著如果一個使用者和一個服務屬於不同的realm,它們就無法互相認證,如果它們不在同一個realm中,但是它們所屬的realm有信任關係,那麼認證就可以通過。本文下面會講到這個被稱為"交叉認證 Cross-Authentiation的機制。

基本上可以認為,只有當一個使用者/服務和一個域的認證服務共享一個密祕(密碼/金鑰)時,這個使用者/服務才屬於這個域。

realm的名字是大小寫敏感的,也就是說,大寫和小寫字元是有區別的,全是通常的realm的名字都用大寫字母。另一個好的實踐是,在一個組織中,讓realm名字和DNS域名一致(但是要大寫)。在選擇realm名字的時候遵循這些建議,將會顯著減少Kerberos客戶端的配置,而且如果想要在子域(subdomain)間建立信任關係,這樣配置是首要的。比如,如果一個組織屬於DNSexample.com,那麼最好把相關的Kerberos realm配成EXAMPLE.COM

 

1.3.2 Principal

 

一個Principal就是一個名字,這個名字用於引用認證服務資料庫中的一個條目。一個Principal和一個特定realm的使用者、主機、或者服務相關聯。Kerberos5中的一個principal有以下的形式:

component1/component2/.../componentN@REALM

但是,在實踐中,最多隻使用兩個component。對於引代一個使用者的條目,它的principal是這樣的形式:

Name[/Instance]@REALM

其中Instance是可選 的,通常用於更好地限定使用者的型別。比如,一個管理員使用者通常會有admin instance(譯註:即Name/admin@REALM這種形式)

下面是指代使用者的 一些principal的例子:

pippo@EXAMPLE.COM    admin/admin@EXAMPLE.COM    pluto/admin@EXAMPLE.COM 

如果,這個條目指代的是服務,那麼principal就需要有以下的形式:

Service/Hostname@REALM

第一部分是service的名字,比如imap, AFS, ftp. 通常'host'這個名字被用於指明對一臺機器的通用的訪問(telnent, rsh, ssh)

第二個component是提供這個服務的機器的完全主機名(FQDN)。這個 componentDNS對應用伺服器的IP地址進行逆向解析後得到的主機名

完全一致是很重要的。下面是指代服務所用的principal的例子:

imap/mbox.example.com@EXAMPLE.COM

host/server.example.com@EXAMPLE.COM

afs/example.com@EXAMPLE.COM

需要指出的是最後一條是一個例外,因為它的第二個compoment不是主機名,而是AFS cell的名字。最後,有一些principal即不用來指代使用者,

也不用於指代服務,而是Kerberos認證系統的操作中扮演一個角色。一個首要的例子就是krbtgt/REALM@REALM,這個principal的金鑰會

被用來加密Tikcet Granting Ticket(我們下面會講到這個)(譯註,krb就是指kerberos, tgt就是指Ticket Granting Ticket,所以這個特殊的principal就是

krbtgt。這個principal的金鑰會被用到加密TGT,只有KDC擁有krbtgt的金鑰,所以TGT才不能被偽造).

 

對於Kerberos 4,永遠不能有超過兩個的components,並且它們之間的分隔符是".", 而不是"/",並且用於指代服務的principalhostname是短

的那種,不是FQDN。下面是可用的例子:

pippo@EXAMPLE.COM    pluto.admin@EXAMPLE.COM    imap.mbox@EXAMPLE.COM

 

1.3.3 Ticket

Ticket是客戶端提供給應用伺服器用於表明自己真實身份的東西(譯註:這是Kerberos的最終目的,大家可以想一下是Kerberos是怎麼基於

對稱密碼演算法做到這一點的)Ticket是認證伺服器(AS, Authentication Server)分發的,並且使用客戶端想要訪問的服務的金鑰加密。由於

加密ticket使用的金鑰是AS和提供服務的伺服器之間的祕密,因此即使請求ticket的客戶端也不能知道或更改它的內容(譯註:所以, ticket

準確的概念是指用service的金鑰加密前的內容,而不是加密後被client提交給service 所在server的那些資料)ticket包括的主要資訊包括:

  • 發出請求的使用者的principal(通常就是使用者名稱)
  • 想要訪問的服務的principal
  • 想要使用這個ticket的客戶端所在機器的IP地址。在Kerberos 5中這個field是可選的,並且可是有多個,以便可以在NAT或者多宿主主機(multihomed)下使用
  • 準備啟用ticket的日期和時間(以時間戳的形式)The date and time when the tickets validity commences
  • ticket的最大生存時間
  • 會話金鑰(session key)(這個金鑰有非常重要的作用,在下面將會描述它的角色)

每個ticket都會有一個過期時間(通常是10小時)。這非常關鍵,因為AS無法控制一個已經分發去出的ticket(譯註:因為AS和提供serviceserver之間是沒有聯絡的。因此,AS是沒辦法主動銷燬一個已經分發出去的ticket)。儘管realm的管理員可以在任何時間停止給特定的使用者分發新的ticket,但是卻無法阻止使用者使用已經擁有的ticket。限制一個ticket的生命週期,就是為了防止無時間限制的濫用。

ticket中還有其它很多資訊和標誌,用來指示它們的行為,但是這篇文章不會講這麼多。我們將會在介紹完認證系統的工作方式以後再來介紹ticket和標誌位。

 

 1.3.4 加密

 

就像你所看到的 一樣,Kerberos經常需要加密和解密在認證過程中的參與者之間傳遞的訊息(ticketauthenticator)(譯註:authenticator的概念後面會講)。需要強調的是,Kerberos只使用對稱加密演算法(也就是說同樣的金鑰即用於加密也用於解密)。某些工程(比如pkinit)致力於引用公鑰系統,利於與特定公鑰相關的私鑰來對初始使用者進行驗證,但是鑑於這種做法並沒有一個標準,所以我們會暫時跳過。

1.3.4.1 加密型別

Kerberos 4只實現了一種加密型別,就56DES。這種加密演算法的脆弱性和一些協議上的漏洞(譯註:指Kerberos 4協議上的漏洞)使得Kerberos 4已經不再使用 了。Kerbeors 5,不同於它的前任,沒有它所支援的加密演算法的數量和型別。而是由Kerberos的不同實現來支援和溝通各種不同的加密演算法(譯註:這裡的溝通應該是指KDCClient間對使用的加密演算法進行溝通)。但是,這種靈活性和可擴充套件性卻加劇了Kerberos的各種實現之間的互操作問題。Kerberos的不同實現的客戶端、程式和認證伺服器之間如果想要互操作(interoperate), 它們必須至少有一種相同的加密演算法。Unix實現的Kerberos 5WindowsActive Directory之間的互操作存在的因難就是一個典型的例子。事實上,Windows Active Directory只支援有限的幾種加密演算法,並且它和UnixKerberos實現間只有56DES是相同的。這就使得如果它們想要互操作的話,56DES必須被啟用,雖然這樣做的風險是眾所周知的。這個問題後來被1.3版本的MIT Kerberos 5解決了。這個版本加入了對RC4-HMAC的支援,這個演算法也被Windows支援,並且比DES更加安全。在Kerberos支援的演算法中(但是不被Windows支援)3DES和更新的AES128AES256值得一提(譯註:這些演算法的安全性都還說得過去,三者之間AES256是最強的,通常AES128已經夠用,而3DES的加解密速度會比較慢。對於JDKAES256需要下policy檔案才能使用)

1.3.4.2 金鑰

在前邊提到過,Kerberos的一個目標就是防止使用者的密碼被以未加密的形式儲存,即使是在認證伺服器的資料庫裡。考慮到不同的加密演算法使用不同的金鑰長度,那麼,很明顯的就是不能強制使用者為每個加密演算法指定一個符合它們長度要求的密碼。因為這個原因,Kerberos引入了string2key函式,這個函式會所未加密的密碼轉化成符合加密演算法要求的長度的金鑰。這個函式在每次使用者更改密碼或者用密碼進行驗證時都會被呼叫。string2key被稱作一個雜湊函式,意思是它是不可逆的:知道金鑰是不能夠推出來生成它時使用的密碼的(除了暴力破解)。最著名的雜湊演算法是MD5CRC32.(譯註:另一個著名的雜湊演算法是SHA系列。CRC32只能生成32位的摘要,因此通常用於做校驗碼。而MD5126SHA1160位,理論上,訊息摘要的長度越大,碰撞的可能性越小)

 

1.3.4.3   Salt

Kerberos5, 不同於Kerberos 4, 引用於密碼鹽(password salt)的概念。鹽被加到密碼的明文的後面,然後再通過string2key函式來獲取金鑰。Kerberos 5使用使用者的principal作為鹽:

Kpippo = string2key ( Ppippo + "pippo@EXAMPLE.COM" )

這種形式的鹽有以下的優點:

  • 屬於同一個realm的兩個principal,即使有相同的密碼,也會有不同的金鑰。比如,如果一個管理員有一個principal用於日常工作(pippo@EXAMPLE.COM),另一個用於管理工作(pippo/admin@EXAMPLE.COM)。很可能這個使用者為了方便,給兩個principal設定了相同的密碼。這種形式的鹽的使用確保了有關聯的金鑰是不同的。
  • 如果一個使用者有兩個在不同的realm中的賬戶,那麼一個普遍的情況就是這兩個賬戶的密碼是相同的:感謝salt的存在,這樣即使一個realm中的帳戶被攻破了,也不會自動異致另一個realm中的賬戶被攻破。

 

Kerberos 5中,也可以指定不用salt,以和Kerberos 4相容。同樣,為了和AFS相容,也可以用配置salt不用principal的完整的名字,而只使用cell的名字。

 

討論了加密型別,string2keysalt之後,就可以檢查一下下面的說法準確性了:為了在不同的Kerberos實現之間相行互操作,它們擁有相同的加密演算法還不夠,它們還必須有相同的string2keysalt

另一點需要注意的是,在解釋string2keysalt的時候,我們只是提了使用者principal,而沒有提server principal。原因很明顯:一個服務,即使和驗證伺服器共享一個祕密,也不會使用 一個未加密的密碼(誰來輸入這個密碼呢?)(譯註:這倒不一定...), 而是一個由管理員生成的金鑰,這個金鑰被儲存(譯註:原文是memorized)在提供服務的伺服器上。

 

1.3.4.4 金鑰版本號(kvno)

當使用者修改密碼或者管理員為應用伺服器升級金鑰的時候,這個修改會被以增加計數器計數的形式記錄下來。計數器的當前值 表示金鑰的版本,這被稱為Key Version Number, 或者簡稱為kvno.

 

1.3.4 金鑰分發中心(KDC)

我們之前講的大都是認證伺服器(authentication server)。因為它是使用者和服務進行身份認證時需要基礎元件,因此我們現在還更深入地看一下它,但是我們不會講解它的操作的所有細節,對這些細節的講解是講解Kerberos協議那個主題提一節所要做的。

在Kerberos環境中,認證伺服器(Authentication Server),由於它具有分發ticket的功能,被稱為金鑰分發中心(Key Distribution Center),或者簡稱為KDC。因為它整個在一個物理的伺服器上(通常就是一個程式),所以它可以從邏輯上分成三部分:資料庫,認證伺服器(Authentication Server)和票據分發伺服器(Ticket Granting Server)。讓我們簡要地分別介紹一下它們。

注意:可以使得一個realm中有Master/Slave形式的冗餘伺服器(MITHeimdal),或者Multimaster結構(Windows Active Directory)。如何獲得冗餘並沒有在Kerberos協議中指定,而是由Kerberos的實現自己確定,因此這裡不進行討論

 

1.3.5.1 資料庫

資料庫是與使用者和服務有關的條目(entry)的容器。我們用principal(也就是條目的名字)來引用一個條目,儘管通常principal這個術語被用和條目混用。每個條目包括以下的資訊:

  • 與這個條目相關聯的principal
  • 金鑰和相關的kvno(譯註: 注意這裡並不是密碼,而是密碼);
  • 與這個principal相關聯的ticket最長可用時間
  • 與這個principal相關聯的ticket的最長的renew時間(譯註:是指這個ticket通過renew機制累計可用的時間)(只在kerberos 5中可用)
  • 決定這個ticket的具體行為的屬性和標誌位。
  • 密碼過期時間
  • 這個principal的過期時間,在此之後就不為這個principal分發ticket了。

為了使得竊取資料庫中的金鑰更加因難,Kerberos的實現們使用master key來對資料庫進行加密,master key被關聯在K/M@REALM這個principal上。即使是資料庫的dump,備份和master KDCsalve KDCpropagation也會被用這個金鑰加密,因此,如果想要重新載入它們,就必須知道這個金鑰。

1.3.5.2 AS

ASKDC是一部分,它用於回覆使用者初始的認證請求,當使用者沒有被認證時,他必須輸入密碼(譯註:也可以使用keytab)。作為對認證請求的響應,AS分發一個特殊的ticket,被稱為Ticket Granting Ticket,簡稱為TGT,與TGT相關聯的principalkrbtgt/REALM@REALM(譯註:意思是TGT使用krbtgt/REALMREALM這個principal的金鑰來加密)。如果使用者的確具有他們所聲稱的身份(將下來我們會看一下他們是怎麼證明這個的),它們就可以使用TGT來獲取其它服務的ticket,而不是重新輸入密碼。

 

1.3.5.3 TGS

KDCTGS元件用於為擁有可用的TGT的客戶端分發service ticket,它可以確保請求一個應用伺服器上的資源的身份的真偽(譯註:意思是,TGS可以確保訪問服務的人的身份是真實的)TGS可以被看成是一個應用伺服器(application server)(因為訪問它必需要使用TGT),它被用來提供給其它服務分發ticket的服務。這裡不能把TGTTGS的字尾:第一個表示ticket,第二個表示service

 

1.3.6  會話金鑰 Session Kery

就像我們所看到的一樣,使用者和服務和KDC共享一個祕密。對於使用者來說,這個祕密就是從密碼推匯出來的金鑰,對於服務來說,就是金鑰(由管理員指定)。這些金鑰被稱為長期金鑰(long term),因為在工會話程改變時,它們是不變的。但是,使用者和服務間也有必要共享祕密,至少當使用者和服務之間存在工作會話的時候:這個金鑰在KDC分發ticket時候生成,稱為Session Key。分發給服務的session key被KDC封裝在ticket(應用伺服器擁有long term key,因此可以從ticket中解碼出session key),分發給使用者的session key被使用使用者的長期金鑰加密封裝。Session key在認證使用者的身份真偽上起了基礎性的角色,我們在接下來的章節中會看到這點。

 

1.3.7 Authenticator

(譯註:這一段對於理解Kerberos認證流程的設計原理非常非常重要)

儘管ticket中含有使用者的principal資訊,並且只有應用伺服器可以獲取和(可能)管理這些資訊(因為ticket被用服務的金鑰加密),但這不足以保證使用者身份的真偽。一個冒名頂替者可以在一個合法的客戶端嚮應用伺服器傳送ticket時捕捉(記住Kerberos的假設是在一個開放以及不安全的網路)這個ticket,並且在適當的時候傳送它,來非法獲取服務。另一方面,在ticket中包含可以使用這個ticketip地址並不是非常有用:眾所周知的是在一個開放和不安全的網路環境中,網各地址可以很容易地偽造。

為了解決這個問題,我們必須利於一個事實:客戶端和伺服器至少在一個公話中共享會話金鑰,並且只有它們知道這個金鑰(KDC也知道,因為正是KDC產生了這個金鑰,但是根據定義,KDC一定是可信的!!!)。因此,以下的策略被採用和包含ticket的請求一起,客戶端新增了另一個包(就是authenticator),使用者的principal和時間戳(當時的時間)被用session key加密後放在這個包裡;提供服務的伺服器在收到這個請求後,解開第一個包,獲取session key,如果使用者的確是他/她所聲稱,那麼伺服器就可以解密authenticator,並且提取時間戳。如果這個時間戳和伺服器的時間相差在兩分種以內(這個值 是可以配置 ),那麼這個認證成功。這個時間給同一個realm中的伺服器的同步劃了一個底線。(譯註:以上的邏輯並不足以阻止攻擊者的重放攻擊。攻擊者可以竊聽客戶最終向伺服器傳送的資訊,即加密後的ticketauthenticator,然後接下來重放這些資訊給伺服器。實際上,Kerberos協議有有制可以阻止這種攻擊。就是伺服器不僅會檢查authenticator中的時間戳,還會檢查它是否曾經見到過這個authenticator。以上這些也表明了Kerberos本身並不能保證客戶端和伺服器之間傳遞的訊息並不會被竊聽,要做到這點,需要對二者建立連線之後的通訊進行加密。)

 

1.3.8 Replay Cache

以下的可能性仍然存在:一個冒名頂替者同時竊取了ticketauthenticator,並且authenticator可用的2分鐘內使用它。這很難,但不是不可能。為了在Kerberos 5中解決這個問題,引入了Replay Cache。應用伺服器application server(也在TGS)可以記住過去兩分種內到達的authenticator,並且拒絕重複的authenticator。只有冒名頂替者沒有能力在合法請求到達前複製ticketauthenticator然後傳送它們到service,他的攻擊就不能得逞。如果他能夠做到的話,那麼真正的使用者就會被拒絕,而冒名頂替者將會成功獲取服務

1.3.9  Credential Cache

客戶端從不儲存使用者的密碼,也不會記住 它通過string2key獲得的金鑰:金鑰被用於解密KDC的回覆並且被立即丟棄。但是,另一方面,為了實現單點登入(singl e sign-on)功能,也就是說使用者在一個工作會話中只被要求輸入一次密碼,必須要儲存ticket和相關的會話金鑰。這些資料被儲存的地方叫做"Credential Cache". 這個cache的位置並不由kerberos協議來指定,而是由它的實現來決定。通常為了可移值性的原因,這個cache被放在檔案系統中(MITHeimdal)。在其它的實現中(AFS  Active Directory),為了增加脆弱的客戶端的安全性,credential cache被放在了一個只有核心 才能訪問的記憶體區域,並且不會被交換到磁碟。

 

相關文章