Kerberos的組件和術語(翻譯和注解)


之所以要翻譯這篇文章,是因為提到了一些通常於對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被放在了一個只有內核 才能訪問的內存區域,並且不會被交換到磁盤。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM