前幾天在給人解釋W(xué)indows是如何通過Kerberos進(jìn)行Authentication的時(shí)候,講了半天也別把那位老兄講明白,還差點(diǎn)把自己給繞進(jìn)去。后來想想原因有以下兩點(diǎn):對(duì)于一個(gè)沒有完全不了解Kerberos的人來說,Kerberos的整個(gè)Authentication過程確實(shí)不好理解——一會(huì)兒以這個(gè)Key進(jìn)行加密、一會(huì)兒又要以另一個(gè)Key進(jìn)行加密,確實(shí)很容易把人給弄暈;另一方面是我講解方式有問題,一開始就從Kerberos的3個(gè)Sub-protocol全面講述整個(gè)Authentication 過程,對(duì)于一個(gè)完全不了解Kerberos的人來說要求也忒高了點(diǎn)。為此,我花了一些時(shí)間寫了這篇文章,盡量以由淺入深、層層深入的方式講述我所理解的基于Kerberos的Windows Network Authentication,希望這篇文章能幫助那些對(duì)Kerberos不明就里的人帶來一絲幫助。對(duì)于一些不對(duì)的地方,歡迎大家批評(píng)指正。
一、 基本原理
Authentication解決的是“如何證明某個(gè)人確確實(shí)實(shí)就是他或她所聲稱的那個(gè)人”的問題。對(duì)于如何進(jìn)行Authentication,我們采用這樣的方法:如果一個(gè)秘密(secret)僅僅存在于A和B,那么有個(gè)人對(duì)B聲稱自己就是A,B通過讓A提供這個(gè)秘密來證明這個(gè)人就是他或她所聲稱的A。這個(gè)過程實(shí)際上涉及到3個(gè)重要的關(guān)于Authentication的方面:
-
Secret如何表示。
-
A如何向B提供Secret。
-
B如何識(shí)別Secret。
基于這3個(gè)方面,我們把Kerberos Authentication進(jìn)行最大限度的簡(jiǎn)化:整個(gè)過程涉及到Client和Server,他們之間的這個(gè)Secret我們用一個(gè)Key(KServer-Client)來表示。Client為了讓Server對(duì)自己進(jìn)行有效的認(rèn)證,向?qū)Ψ教峁┤缦聝山M信息:
-
代表Client自身Identity的信息,為了簡(jiǎn)便,它以明文的形式傳遞。
-
將Client的Identity使用KServer-Client作為Public Key、并采用對(duì)稱加密算法進(jìn)行加密。
由于KServer-Client僅僅被Client和Server知曉,所以被Client使用KServer-Client加密過的Client Identity只能被Client和Server解密。同理,Server接收到Client傳送的這兩組信息,先通過KServer-Client對(duì)后者進(jìn)行解密,隨后將機(jī)密的數(shù)據(jù)同前者進(jìn)行比較,如果完全一樣,則可以證明Client能過提供正確的KServer-Client,而這個(gè)世界上,僅僅只有真正的Client和自己知道KServer-Client,所以可以對(duì)方就是他所聲稱的那個(gè)人。
Keberos大體上就是按照這樣的一個(gè)原理來進(jìn)行Authentication的。但是Kerberos遠(yuǎn)比這個(gè)復(fù)雜,我將在后續(xù)的章節(jié)中不斷地?cái)U(kuò)充這個(gè)過程,知道Kerberos真實(shí)的認(rèn)證過程。為了使讀者更加容易理解后續(xù)的部分,在這里我們先給出兩個(gè)重要的概念:
-
Long-term Key/Master Key:在Security的領(lǐng)域中,有的Key可能長(zhǎng)期內(nèi)保持不變,比如你在密碼,可能幾年都不曾改變,這樣的Key、以及由此派生的Key被稱為L(zhǎng)ong-term Key。對(duì)于Long-term Key的使用有這樣的原則:被Long-term Key加密的數(shù)據(jù)不應(yīng)該在網(wǎng)絡(luò)上傳輸。原因很簡(jiǎn)單,一旦這些被Long-term Key加密的數(shù)據(jù)包被惡意的網(wǎng)絡(luò)監(jiān)聽者截獲,在原則上,只要有充足的時(shí)間,他是可以通過計(jì)算獲得你用于加密的Long-term Key的——任何加密算法都不可能做到絕對(duì)保密。
在一般情況下,對(duì)于一個(gè)Account來說,密碼往往僅僅限于該Account的所有者知曉,甚至對(duì)于任何Domain的Administrator,密碼仍然應(yīng)該是保密的。但是密碼卻又是證明身份的憑據(jù),所以必須通過基于你密碼的派生的信息來證明用戶的真實(shí)身份,在這種情況下,一般將你的密碼進(jìn)行Hash運(yùn)算得到一個(gè)Hash code, 我們一般管這樣的Hash Code叫做Master Key。由于Hash Algorithm是不可逆的,同時(shí)保證密碼和Master Key是一一對(duì)應(yīng)的,這樣既保證了你密碼的保密性,有同時(shí)保證你的Master Key和密碼本身在證明你身份的時(shí)候具有相同的效力。
-
Short-term Key/Session Key:由于被Long-term Key加密的數(shù)據(jù)包不能用于網(wǎng)絡(luò)傳送,所以我們使用另一種Short-term Key來加密需要進(jìn)行網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)。由于這種Key只在一段時(shí)間內(nèi)有效,即使被加密的數(shù)據(jù)包被黑客截獲,等他把Key計(jì)算出來的時(shí)候,這個(gè)Key早就已經(jīng)過期了。
二、引入Key Distribution: KServer-Client從何而來
上面我們討論了Kerberos Authentication的基本原理:通過讓被認(rèn)證的一方提供一個(gè)僅限于他和認(rèn)證方知曉的Key來鑒定對(duì)方的真實(shí)身份。而被這個(gè)Key加密的數(shù)據(jù)包需要在Client和Server之間傳送,所以這個(gè)Key不能是一個(gè)Long-term Key,而只可能是Short-term Key,這個(gè)可以僅僅在Client和Server的一個(gè)Session中有效,所以我們稱這個(gè)Key為Client和Server之間的Session Key(SServer-Client)。
現(xiàn)在我們來討論Client和Server如何得到這個(gè)SServer-Client。在這里我們要引入一個(gè)重要的角色:Kerberos Distribution Center-KDC。KDC在整個(gè)Kerberos Authentication中作為Client和Server共同信任的第三方起著重要的作用,而Kerberos的認(rèn)證過程就是通過這3方協(xié)作完成。順便說一下,Kerberos起源于希臘神話,是一支守護(hù)著冥界長(zhǎng)著3個(gè)頭顱的神犬,在keberos Authentication中,Kerberos的3個(gè)頭顱代表中認(rèn)證過程中涉及的3方:Client、Server和KDC。
對(duì)于一個(gè)Windows Domain來說,Domain Controller扮演著KDC的角色。KDC維護(hù)著一個(gè)存儲(chǔ)著該Domain中所有帳戶的Account Database(一般地,這個(gè)Account Database由AD來維護(hù)),也就是說,他知道屬于每個(gè)Account的名稱和派生于該Account Password的Master Key。而用于Client和Server相互認(rèn)證的SServer-Client就是有KDC分發(fā)。下面我們來看看KDC分發(fā)SServer-Client的過程。
通過下圖我們可以看到KDC分發(fā)SServer-Client的簡(jiǎn)單的過程:首先Client向KDC發(fā)送一個(gè)對(duì)SServer-Client的申請(qǐng)。這個(gè)申請(qǐng)的內(nèi)容可以簡(jiǎn)單概括為“我是某個(gè)Client,我需要一個(gè)Session Key用于訪問某個(gè)Server ”。KDC在接收到這個(gè)請(qǐng)求的時(shí)候,生成一個(gè)Session Key,為了保證這個(gè)Session Key僅僅限于發(fā)送請(qǐng)求的Client和他希望訪問的Server知曉,KDC會(huì)為這個(gè)Session Key生成兩個(gè)Copy,分別被Client和Server使用。然后從Account database中提取Client和Server的Master Key分別對(duì)這兩個(gè)Copy進(jìn)行對(duì)稱加密。對(duì)于后者,和Session Key一起被加密的還包含關(guān)于Client的一些信息。
KDC現(xiàn)在有了兩個(gè)分別被Client和Server 的Master Key加密過的Session Key,這兩個(gè)Session Key如何分別被Client和Server獲得呢?也許你 馬上會(huì)說,KDC直接將這兩個(gè)加密過的包發(fā)送給Client和Server不就可以了嗎,但是如果這樣做,對(duì)于Server來說會(huì)出現(xiàn)下面 兩個(gè)問題:
-
由于一個(gè)Server會(huì)面對(duì)若干不同的Client, 而每個(gè)Client都具有一個(gè)不同的Session Key。那么Server就會(huì)為所有的Client維護(hù)這樣一個(gè)Session Key的列表,這樣做對(duì)于Server來說是比較麻煩而低效的。
-
由于網(wǎng)絡(luò)傳輸?shù)牟淮_定性,可能出現(xiàn)這樣一種情況:Client很快獲得Session Key,并將這個(gè)Session Key作為Credential隨同訪問請(qǐng)求發(fā)送到Server,但是用于Server的Session Key確還沒有收到,并且很有可能承載這個(gè)Session Key的永遠(yuǎn)也到不了Server端,Client將永遠(yuǎn)得不到認(rèn)證。
為了解決這個(gè)問題,Kerberos的做法很簡(jiǎn)單,將這兩個(gè)被加密的Copy一并發(fā)送給Client,屬于Server的那份由Client發(fā)送給Server。
可能有人會(huì)問,KDC并沒有真正去認(rèn)證這個(gè)發(fā)送請(qǐng)求的Client是否真的就是那個(gè)他所聲稱的那個(gè)人,就把Session Key發(fā)送給他,會(huì)不會(huì)有什么問題?如果另一個(gè)人(比如Client B)聲稱自己是Client A,他同樣會(huì)得到Client A和Server的Session Key,這會(huì)不會(huì)有什么問題?實(shí)際上不存在問題,因?yàn)镃lient B聲稱自己是Client A,KDC就會(huì)使用Client A的Password派生的Master Key對(duì)Session Key進(jìn)行加密,所以真正知道Client A 的Password的一方才會(huì)通過解密獲得Session Key。
三、引入Authenticator - 為有效的證明自己提供證據(jù)
通過上面的過程,Client實(shí)際上獲得了兩組信息:一個(gè)通過自己Master Key加密的Session Key,另一個(gè)被Sever的Master Key加密的數(shù)據(jù)包,包含Session Key和關(guān)于自己的一些確認(rèn)信息。通過第一節(jié),我們說只要通過一個(gè)雙方知曉的Key就可以對(duì)對(duì)方進(jìn)行有效的認(rèn)證,但是在一個(gè)網(wǎng)絡(luò)的環(huán)境中,這種簡(jiǎn)單的做法是具有安全漏洞,為此,Client需要提供更多的證明信息,我們把這種證明信息稱為Authenticator,在Kerberos的Authenticator實(shí)際上就是關(guān)于Client的一些信息和當(dāng)前時(shí)間的一個(gè)Timestamp(關(guān)于這個(gè)安全漏洞和Timestamp的作用,我將在后面解釋)。
在這個(gè)基礎(chǔ)上,我們?cè)賮砜纯碨erver如何對(duì)Client進(jìn)行認(rèn)證:Client通過自己的Master Key對(duì)KDC加密的Session Key進(jìn)行解密從而獲得Session Key,隨后創(chuàng)建Authenticator(Client Info + Timestamp)并用Session Key對(duì)其加密。最后連同從KDC獲得的、被Server的Master Key加密過的數(shù)據(jù)包(Client Info + Session Key)一并發(fā)送到Server端。我們把通過Server的Master Key加密過的數(shù)據(jù)包稱為Session Ticket。
當(dāng)Server接收到這兩組數(shù)據(jù)后,先使用他自己的Master Key對(duì)Session Ticket進(jìn)行解密,從而獲得Session Key。隨后使用該Session Key解密Authenticator,通過比較Authenticator中的Client Info和Session Ticket中的Client Info從而實(shí)現(xiàn)對(duì)Client的認(rèn)證。
為什么要使用Timestamp?
到這里,很多人可能認(rèn)為這樣的認(rèn)證過程天衣無縫:只有當(dāng)Client提供正確的Session Key方能得到Server的認(rèn)證。但是在現(xiàn)實(shí)環(huán)境中,這存在很大的安全漏洞。
我們?cè)囅脒@樣的現(xiàn)象:Client向Server發(fā)送的數(shù)據(jù)包被某個(gè)惡意網(wǎng)絡(luò)監(jiān)聽者截獲,該監(jiān)聽者隨后將數(shù)據(jù)包座位自己的Credential冒充該Client對(duì)Server進(jìn)行訪問,在這種情況下,依然可以很順利地獲得Server的成功認(rèn)證。為了解決這個(gè)問題,Client在Authenticator中會(huì)加入一個(gè)當(dāng)前時(shí)間的Timestamp。
在Server對(duì)Authenticator中的Client Info和Session Ticket中的Client Info進(jìn)行比較之前,會(huì)先提取Authenticator中的Timestamp,并同當(dāng)前的時(shí)間進(jìn)行比較,如果他們之間的偏差超出一個(gè)可以接受的時(shí)間范圍(一般是5mins),Server會(huì)直接拒絕該Client的請(qǐng)求。在這里需要知道的是,Server維護(hù)著一個(gè)列表,這個(gè)列表記錄著在這個(gè)可接受的時(shí)間范圍內(nèi)所有進(jìn)行認(rèn)證的Client和認(rèn)證的時(shí)間。對(duì)于時(shí)間偏差在這個(gè)可接受的范圍中的Client,Server會(huì)從這個(gè)這個(gè)列表中獲得最近一個(gè)該Client的認(rèn)證時(shí)間,只有當(dāng)Authenticator中的Timestamp晚于通過一個(gè)Client的最近的認(rèn)證時(shí)間的情況下,Server采用進(jìn)行后續(xù)的認(rèn)證流程。
Time Synchronization的重要性
上述 基于Timestamp的認(rèn)證機(jī)制只有在Client和Server端的時(shí)間保持同步的情況才有意義。所以保持Time Synchronization在整個(gè)認(rèn)證過程中顯得尤為重要。在一個(gè)Domain中,一般通過訪問同一個(gè)Time Service獲得當(dāng)前時(shí)間的方式來實(shí)現(xiàn)時(shí)間的同步。
雙向認(rèn)證(Mutual Authentication)
Kerberos一個(gè)重要的優(yōu)勢(shì)在于它能夠提供雙向認(rèn)證:不但Server可以對(duì)Client 進(jìn)行認(rèn)證,Client也能對(duì)Server進(jìn)行認(rèn)證。
具體過程是這樣的,如果Client需要對(duì)他訪問的Server進(jìn)行認(rèn)證,會(huì)在它向Server發(fā)送的Credential中設(shè)置一個(gè)是否需要認(rèn)證的Flag。Server在對(duì)Client認(rèn)證成功之后,會(huì)把Authenticator中的Timestamp提出出來,通過Session Key進(jìn)行加密,當(dāng)Client接收到并使用Session Key進(jìn)行解密之后,如果確認(rèn)Timestamp和原來的完全一致,那么他可以認(rèn)定Server正式他試圖訪問的Server。
那么為什么Server不直接把通過Session Key進(jìn)行加密的Authenticator原樣發(fā)送給Client,而要把Timestamp提取出來加密發(fā)送給Client呢?原因在于防止惡意的監(jiān)聽者通過獲取的Client發(fā)送的Authenticator冒充Server獲得Client的認(rèn)證。
四、引入Ticket Granting Service
通過上面的介紹,我們發(fā)現(xiàn)Kerberos實(shí)際上一個(gè)基于Ticket的認(rèn)證方式。Client想要獲取Server端的資源,先得通過Server的認(rèn)證;而認(rèn)證的先決條件是Client向Server提供從KDC獲得的一個(gè)有Server的Master Key進(jìn)行加密的Session Ticket(Session Key + Client Info)??梢赃@么說,Session Ticket是Client進(jìn)入Server領(lǐng)域的一張門票。而這張門票必須從一個(gè)合法的Ticket頒發(fā)機(jī)構(gòu)獲得,這個(gè)頒發(fā)機(jī)構(gòu)就是Client和Server雙方信任的KDC, 同時(shí)這張Ticket具有超強(qiáng)的防偽標(biāo)識(shí):它是被Server的Master Key加密的。對(duì)Client來說, 獲得Session Ticket是整個(gè)認(rèn)證過程中最為關(guān)鍵的部分。
上面我們只是簡(jiǎn)單地從大體上說明了KDC向Client分發(fā)Ticket的過程,而真正在Kerberos中的Ticket Distribution要復(fù)雜一些。為了更好的說明整個(gè)Ticket Distribution的過程,我在這里做一個(gè)類比?,F(xiàn)在的股事很火爆,上海基本上是全民炒股,我就舉一個(gè)認(rèn)股權(quán)證的例子。有的上市公司在股票配股、增發(fā)、基金擴(kuò)募、股份減持等情況會(huì)向公眾發(fā)行認(rèn)股權(quán)證,認(rèn)股權(quán)證的持有人可以憑借這個(gè)權(quán)證認(rèn)購(gòu)一定數(shù)量的該公司股票,認(rèn)股權(quán)證是一種具有看漲期權(quán)的金融衍生產(chǎn)品。
而我們今天所講的Client獲得Ticket的過程也和通過認(rèn)股權(quán)證購(gòu)買股票的過程類似。如果我們把Client提供給Server進(jìn)行認(rèn)證的Ticket比作股票的話,那么Client在從KDC那邊獲得Ticket之前,需要先獲得這個(gè)Ticket的認(rèn)購(gòu)權(quán)證,這個(gè)認(rèn)購(gòu)權(quán)證在Kerberos中被稱為TGT:Ticket Granting Ticket,TGT的分發(fā)方仍然是KDC。
我們現(xiàn)在來看看Client是如何從KDC處獲得TGT的:首先Client向KDC發(fā)起對(duì)TGT的申請(qǐng),申請(qǐng)的內(nèi)容大致可以這樣表示:“我需要一張TGT用以申請(qǐng)獲取用以訪問所有Server的Ticket”。KDC在收到該申請(qǐng)請(qǐng)求后,生成一個(gè)用于該Client和KDC進(jìn)行安全通信的Session Key(SKDC-Client)。為了保證該Session Key僅供該Client和自己使用,KDC使用Client的Master Key和自己的Master Key對(duì)生成的Session Key進(jìn)行加密,從而獲得兩個(gè)加密的SKDC-Client的Copy。對(duì)于后者,隨SKDC-Client一起被加密的還包含以后用于鑒定Client身份的關(guān)于Client的一些信息。最后KDC將這兩份Copy一并發(fā)送給Client。這里有一點(diǎn)需要注意的是:為了免去KDC對(duì)于基于不同Client的Session Key進(jìn)行維護(hù)的麻煩,就像Server不會(huì)保存Session Key(SServer-Client)一樣,KDC也不會(huì)去保存這個(gè)Session Key(SKDC-Client),而選擇完全靠Client自己提供的方式。
當(dāng)Client收到KDC的兩個(gè)加密數(shù)據(jù)包之后,先使用自己的Master Key對(duì)第一個(gè)Copy進(jìn)行解密,從而獲得KDC和Client的Session Key(SKDC-Client),并把該Session 和TGT進(jìn)行緩存。有了Session Key和TGT,Client自己的Master Key將不再需要,因?yàn)榇撕驝lient可以使用SKDC-Client向KDC申請(qǐng)用以訪問每個(gè)Server的Ticket,相對(duì)于Client的Master Key這個(gè)Long-term Key,SKDC-Client是一個(gè)Short-term Key,安全保證得到更好的保障,這也是Kerberos多了這一步的關(guān)鍵所在。同時(shí)需要注意的是SKDC-Client是一個(gè)Session Key,他具有自己的生命周期,同時(shí)TGT和Session相互關(guān)聯(lián),當(dāng)Session Key過期,TGT也就宣告失效,此后Client不得不重新向KDC申請(qǐng)新的TGT,KDC將會(huì)生成一個(gè)不同Session Key和與之關(guān)聯(lián)的TGT。同時(shí),由于Client Log off也導(dǎo)致SKDC-Client的失效,所以SKDC-Client又被稱為Logon Session Key。
接下來,我們看看Client如何使用TGT來從KDC獲得基于某個(gè)Server的Ticket。在這里我要強(qiáng)調(diào)一下,Ticket是基于某個(gè)具體的Server的,而TGT則是和具體的Server無關(guān)的,Client可以使用一個(gè)TGT從KDC獲得基于不同Server的Ticket。我們言歸正傳,Client在獲得自己和KDC的Session Key(SKDC-Client)之后,生成自己的Authenticator以及所要訪問的Server名稱的并使用SKDC-Client進(jìn)行加密。隨后連同TGT一并發(fā)送給KDC。KDC使用自己的Master Key對(duì)TGT進(jìn)行解密,提取Client Info和Session Key(SKDC-Client),然后使用這個(gè)SKDC-Client解密Authenticator獲得Client Info,對(duì)兩個(gè)Client Info進(jìn)行比較進(jìn)而驗(yàn)證對(duì)方的真實(shí)身份。驗(yàn)證成功,生成一份基于Client所要訪問的Server的Ticket給Client,這個(gè)過程就是我們第二節(jié)中介紹的一樣了。
五、Kerberos的3個(gè)Sub-protocol:整個(gè)Authentication
通過以上的介紹,我們基本上了解了整個(gè)Kerberos authentication的整個(gè)流程:整個(gè)流程大體上包含以下3個(gè)子過程:
-
Client向KDC申請(qǐng)TGT(Ticket Granting Ticket)。
-
Client通過獲得TGT向DKC申請(qǐng)用于訪問Server的Ticket。
-
Client最終向?yàn)榱薙erver對(duì)自己的認(rèn)證向其提交Ticket。
不過上面的介紹離真正的Kerberos Authentication還是有一點(diǎn)出入。Kerberos整個(gè)認(rèn)證過程通過3個(gè)sub-protocol來完成。這個(gè)3個(gè)Sub-Protocol分別完成上面列出的3個(gè)子過程。這3個(gè)sub-protocol分別為:
-
Authentication Service Exchange
-
Ticket Granting Service Exchange
-
Client/Server Exchange
下圖簡(jiǎn)單展示了完成這個(gè)3個(gè)Sub-protocol所進(jìn)行Message Exchange。
1. Authentication Service Exchange
通過這個(gè)Sub-protocol,KDC(確切地說是KDC中的Authentication Service)實(shí)現(xiàn)對(duì)Client身份的確認(rèn),并頒發(fā)給該Client一個(gè)TGT。具體過程如下:
Client向KDC的Authentication Service發(fā)送Authentication Service Request(KRB_AS_REQ), 為了確保KRB_AS_REQ僅限于自己和KDC知道,Client使用自己的Master Key對(duì)KRB_AS_REQ的主體部分進(jìn)行加密(KDC可以通過Domain 的Account Database獲得該Client的Master Key)。KRB_AS_REQ的大體包含以下的內(nèi)容:
-
Pre-authentication data:包含用以證明自己身份的信息。說白了,就是證明自己知道自己聲稱的那個(gè)account的Password。一般地,它的內(nèi)容是一個(gè)被Client的Master key加密過的Timestamp。
-
Client name & realm: 簡(jiǎn)單地說就是Domain name\Client
-
Server Name:注意這里的Server Name并不是Client真正要訪問的Server的名稱,而我們也說了TGT是和Server無關(guān)的(Client只能使用Ticket,而不是TGT去訪問Server)。這里的Server Name實(shí)際上是KDC的Ticket Granting Service的Server Name。
AS(Authentication Service)通過它接收到的KRB_AS_REQ驗(yàn)證發(fā)送方的是否是在Client name & realm中聲稱的那個(gè)人,也就是說要驗(yàn)證發(fā)送放是否知道Client的Password。所以AS只需從Account Database中提取Client對(duì)應(yīng)的Master Key對(duì)Pre-authentication data進(jìn)行解密,如果是一個(gè)合法的Timestamp,則可以證明發(fā)送放提供的是正確無誤的密碼。驗(yàn)證通過之后,AS將一份Authentication Service Response(KRB_AS_REP)發(fā)送給Client。KRB_AS_REQ主要包含兩個(gè)部分:本Client的Master Key加密過的Session Key(SKDC-Client:Logon Session Key)和被自己(KDC)加密的TGT。而TGT大體又包含以下的內(nèi)容:
-
Session Key: SKDC-Client:Logon Session Key
-
Client name & realm: 簡(jiǎn)單地說就是Domain name\Client
-
End time: TGT到期的時(shí)間。
Client通過自己的Master Key對(duì)第一部分解密獲得Session Key(SKDC-Client:Logon Session Key)之后,攜帶著TGT便可以進(jìn)入下一步:TGS(Ticket Granting Service)Exchange。
2. TGS(Ticket Granting Service)Exchange
TGS(Ticket Granting Service)Exchange通過Client向KDC中的TGS(Ticket Granting Service)發(fā)送Ticket Granting Service Request(KRB_TGS_REQ)開始。KRB_TGS_REQ大體包含以下的內(nèi)容:
-
TGT:Client通過AS Exchange獲得的Ticket Granting Ticket,TGT被KDC的Master Key進(jìn)行加密。
-
Authenticator:用以證明當(dāng)初TGT的擁有者是否就是自己,所以它必須以TGT的辦法方和自己的Session Key(SKDC-Client:Logon Session Key)來進(jìn)行加密。
-
Client name & realm: 簡(jiǎn)單地說就是Domain name\Client。
-
Server name & realm: 簡(jiǎn)單地說就是Domain name\Server,這回是Client試圖訪問的那個(gè)Server。
TGS收到KRB_TGS_REQ在發(fā)給Client真正的Ticket之前,先得整個(gè)Client提供的那個(gè)TGT是否是AS頒發(fā)給它的。于是它不得不通過Client提供的Authenticator來證明。但是Authentication是通過Logon Session Key(SKDC-Client)進(jìn)行加密的,而自己并沒有保存這個(gè)Session Key。所以TGS先得通過自己的Master Key對(duì)Client提供的TGT進(jìn)行解密,從而獲得這個(gè)Logon Session Key(SKDC-Client),再通過這個(gè)Logon Session Key(SKDC-Client)解密Authenticator進(jìn)行驗(yàn)證。驗(yàn)證通過向?qū)Ψ桨l(fā)送Ticket Granting Service Response(KRB_TGS_REP)。這個(gè)KRB_TGS_REP有兩部分組成:使用Logon Session Key(SKDC-Client)加密過用于Client和Server的Session Key(SServer-Client)和使用Server的Master Key進(jìn)行加密的Ticket。該Ticket大體包含以下一些內(nèi)容:
-
Session Key:SServer-Client。
-
Client name & realm: 簡(jiǎn)單地說就是Domain name\Client。
-
End time: Ticket的到期時(shí)間。
Client收到KRB_TGS_REP,使用Logon Session Key(SKDC-Client)解密第一部分后獲得Session Key(SServer-Client)。有了Session Key和Ticket,Client就可以之間和Server進(jìn)行交互,而無須在通過KDC作中間人了。所以我們說Kerberos是一種高效的認(rèn)證方式,它可以直接通過Client和Server雙方來完成,不像Windows NT 4下的NTLM認(rèn)證方式,每次認(rèn)證都要通過一個(gè)雙方信任的第3方來完成。
我們現(xiàn)在來看看 Client如果使用Ticket和Server怎樣進(jìn)行交互的,這個(gè)階段通過我們的第3個(gè)Sub-protocol來完成:CS(Client/Server )Exchange。
3. CS(Client/Server )Exchange
這個(gè)已經(jīng)在本文的第二節(jié)中已經(jīng)介紹過,對(duì)于重復(fù)發(fā)內(nèi)容就不再累贅了。Client通過TGS Exchange獲得Client和Server的Session Key(SServer-Client),隨后創(chuàng)建用于證明自己就是Ticket的真正所有者的Authenticator,并使用Session Key(SServer-Client)進(jìn)行加密。最后將這個(gè)被加密過的Authenticator和Ticket作為Application Service Request(KRB_AP_REQ)發(fā)送給Server。除了上述兩項(xiàng)內(nèi)容之外,KRB_AP_REQ還包含一個(gè)Flag用于表示Client是否需要進(jìn)行雙向驗(yàn)證(Mutual Authentication)。
Server接收到KRB_AP_REQ之后,通過自己的Master Key解密Ticket,從而獲得Session Key(SServer-Client)。通過Session Key(SServer-Client)解密Authenticator,進(jìn)而驗(yàn)證對(duì)方的身份。驗(yàn)證成功,讓Client訪問需要訪問的資源,否則直接拒絕對(duì)方的請(qǐng)求。
對(duì)于需要進(jìn)行雙向驗(yàn)證,Server從Authenticator提取Timestamp,使用Session Key(SServer-Client)進(jìn)行加密,并將其發(fā)送給Client用于Client驗(yàn)證Server的身份。
六、User2User Sub-Protocol:有效地保障Server的安全
通過3個(gè)Sub-protocol的介紹,我們可以全面地掌握整個(gè)Kerberos的認(rèn)證過程。實(shí)際上,在Windows 2000時(shí)代,基于Kerberos的Windows Authentication就是按照這樣的工作流程來進(jìn)行的。但是我在上面一節(jié)結(jié)束的時(shí)候也說了,基于3個(gè)Sub-protocol的Kerberos作為一種Network Authentication是具有它自己的局限和安全隱患的。我在整篇文章一直在強(qiáng)調(diào)這樣的一個(gè)原則:以某個(gè)Entity的Long-term Key加密的數(shù)據(jù)不應(yīng)該在網(wǎng)絡(luò)中傳遞。原因很簡(jiǎn)單,所有的加密算法都不能保證100%的安全,對(duì)加密的數(shù)據(jù)進(jìn)行解密只是一個(gè)時(shí)間的過程,最大限度地提供安全保障的做法就是:使用一個(gè)Short-term key(Session Key)代替Long-term Key對(duì)數(shù)據(jù)進(jìn)行加密,使得惡意用戶對(duì)其解密獲得加密的Key時(shí),該Key早已失效。但是對(duì)于3個(gè)Sub-Protocol的C/S Exchange,Client攜帶的Ticket卻是被Server Master Key進(jìn)行加密的,這顯現(xiàn)不符合我們提出的原則,降低Server的安全系數(shù)。
所以我們必須尋求一種解決方案來解決上面的問題。這個(gè)解決方案很明顯:就是采用一個(gè)Short-term的Session Key,而不是Server Master Key對(duì)Ticket進(jìn)行加密。這就是我們今天要介紹的Kerberos的第4個(gè)Sub-protocol:User2User Protocol。我們知道,既然是Session Key,僅必然涉及到兩方,而在Kerberos整個(gè)認(rèn)證過程涉及到3方:Client、Server和KDC,所以用于加密Ticket的只可能是Server和KDC之間的Session Key(SKDC-Server)。
我們知道Client通過在AS Exchange階段獲得的TGT從KDC那么獲得訪問Server的Ticket。原來的Ticket是通過Server的Master Key進(jìn)行加密的,而這個(gè)Master Key可以通過Account Database獲得。但是現(xiàn)在KDC需要使用Server和KDC之間的SKDC-Server進(jìn)行加密,而KDC是不會(huì)維護(hù)這個(gè)Session Key,所以這個(gè)Session Key只能靠申請(qǐng)Ticket的Client提供。所以在AS Exchange和TGS Exchange之間,Client還得對(duì)Server進(jìn)行請(qǐng)求已獲得Server和KDC之間的Session Key(SKDC-Server)。而對(duì)于Server來說,它可以像Client一樣通過AS Exchange獲得他和KDC之間的Session Key(SKDC-Server)和一個(gè)封裝了這個(gè)Session Key并被KDC的Master Key進(jìn)行加密的TGT,一旦獲得這個(gè)TGT,Server會(huì)緩存它,以待Client對(duì)它的請(qǐng)求。我們現(xiàn)在來詳細(xì)地討論這一過程。
上圖基本上翻譯了基于User2User的認(rèn)證過程,這個(gè)過程由4個(gè)步驟組成。我們發(fā)現(xiàn)較之我在上面一節(jié)介紹的基于傳統(tǒng)3個(gè)Sub-protocol的認(rèn)證過程,這次對(duì)了第2部。我們從頭到尾簡(jiǎn)單地過一遍:
-
AS Exchange:Client通過此過程獲得了屬于自己的TGT,有了此TGT,Client可憑此向KDC申請(qǐng)用于訪問某個(gè)Server的Ticket。
-
這一步的主要任務(wù)是獲得封裝了Server和KDC的Session Key(SKDC-Server)的屬于Server的TGT。如果該TGT存在于Server的緩存中,則Server會(huì)直接將其返回給Client。否則通過AS Exchange從KDC獲取。
-
TGS Exchange:Client通過向KDC提供自己的TGT,Server的TGT以及Authenticator向KDC申請(qǐng)用于訪問Server的Ticket。KDC使用先用自己的Master Key解密Client的TGT獲得SKDC-Client,通過SKDC-Client解密Authenticator驗(yàn)證發(fā)送者是否是TGT的真正擁有者,驗(yàn)證通過再用自己的Master Key解密Server的TGT獲得KDC和Server 的Session Key(SKDC-Server),并用該Session Key加密Ticket返回給Client。
-
C/S Exchange:Client攜帶者通過KDC和Server 的Session Key(SKDC-Server)進(jìn)行加密的Ticket和通過Client和Server的Session Key(SServer-Client)的Authenticator訪問Server,Server通過SKDC-Server解密Ticket獲得SServer-Client,通過SServer-Client解密Authenticator實(shí)現(xiàn)對(duì)Client的驗(yàn)證。
這就是整個(gè)過程。
七、Kerberos的優(yōu)點(diǎn)
分析整個(gè)Kerberos的認(rèn)證過程之后,我們來總結(jié)一下Kerberos都有哪些優(yōu)點(diǎn):
1.較高的Performance
雖然我們一再地說Kerberos是一個(gè)涉及到3方的認(rèn)證過程:Client、Server、KDC。但是一旦Client獲得用過訪問某個(gè)Server的Ticket,該Server就能根據(jù)這個(gè)Ticket實(shí)現(xiàn)對(duì)Client的驗(yàn)證,而無須KDC的再次參與。和傳統(tǒng)的基于Windows NT 4.0的每個(gè)完全依賴Trusted Third Party的NTLM比較,具有較大的性能提升。
2.實(shí)現(xiàn)了雙向驗(yàn)證(Mutual Authentication)
傳統(tǒng)的NTLM認(rèn)證基于這樣一個(gè)前提:Client訪問的遠(yuǎn)程的Service是可信的、無需對(duì)于進(jìn)行驗(yàn)證,所以NTLM不曾提供雙向驗(yàn)證的功能。這顯然有點(diǎn)理想主義,為此Kerberos彌補(bǔ)了這個(gè)不足:Client在訪問Server的資源之前,可以要求對(duì)Server的身份執(zhí)行認(rèn)證。
3.對(duì)Delegation的支持
Impersonation和Delegation是一個(gè)分布式環(huán)境中兩個(gè)重要的功能。Impersonation允許Server在本地使用Logon 的Account執(zhí)行某些操作,Delegation需用Server將logon的Account帶入到另過一個(gè)Context執(zhí)行相應(yīng)的操作。NTLM僅對(duì)Impersonation提供支持,而Kerberos通過一種雙向的、可傳遞的(Mutual 、Transitive)信任模式實(shí)現(xiàn)了對(duì)Delegation的支持。
4.互操作性(Interoperability)
Kerberos最初由MIT首創(chuàng),現(xiàn)在已經(jīng)成為一行被廣泛接受的標(biāo)準(zhǔn)。所以對(duì)于不同的平臺(tái)可以進(jìn)行廣泛的互操作。