Windows安全認(rèn)證是如何進(jìn)行的?
最近一段時(shí)間都在折騰安全(Security)方面的東西,比如Windows認(rèn)證、非對(duì)稱(chēng)加密、數(shù)字證書(shū)、數(shù)字簽名、TLS/SSL、WS-Security等。如果時(shí)間允許,我很樂(lè)意寫(xiě)一系列的文章與廣大網(wǎng)友分享、交流。對(duì)于很多讀者來(lái)說(shuō),今天討論的可能是一個(gè)既熟悉、又陌生的話題——Windows認(rèn)證。
目錄
一、Kerberos認(rèn)證簡(jiǎn)介
二、如何獲得“認(rèn)購(gòu)權(quán)證”?
三、如何通過(guò)“認(rèn)購(gòu)權(quán)證”購(gòu)買(mǎi)“入場(chǎng)券”?
四、憑票入場(chǎng)
一、Kerberos認(rèn)證簡(jiǎn)介

Windows認(rèn)證協(xié)議有兩種NTLM(NT LAN Manager)和Kerberos,前者主要應(yīng)用于用于Windows NT 和 Windows 2000 Server(or Later) 工作組環(huán)境,而后者則主要應(yīng)用于Windows 2000 Server(or Later) 域(Domain)環(huán)境。Kerberos較之NTLM更高效、更安全,同時(shí)認(rèn)證過(guò)程也相對(duì)復(fù)雜。Kerberos這個(gè)名字來(lái)源于希臘神話,是冥界守護(hù)神獸的名字。Kerberos是一個(gè)三頭怪獸,之所以用它來(lái)命名一種完全認(rèn)證協(xié)議,是因?yàn)檎麄€(gè)認(rèn)證過(guò)程涉及到三方:客戶端、服務(wù)端和KDC(Key Distribution Center)。在Windows域環(huán)境中,KDC的角色由DC(Domain Controller)來(lái)?yè)?dān)當(dāng)。
某個(gè)用戶采用某個(gè)域帳號(hào)登錄到某臺(tái)主機(jī),并遠(yuǎn)程訪問(wèn)處于相同域中另一臺(tái)主機(jī)時(shí),如何對(duì)訪問(wèn)者和被訪問(wèn)者進(jìn)行身份驗(yàn)證(這是一種雙向的驗(yàn)證)?這就是Kerberos需要解決的場(chǎng)景。接下來(lái)我盡量以比較直白的語(yǔ)言來(lái)介紹我所知道的Kerberos認(rèn)證的整個(gè)流程。
Kerberos實(shí)際上是一種基于票據(jù)(Ticket)的認(rèn)證方式。客戶端要訪問(wèn)服務(wù)器的資源,需要首先購(gòu)買(mǎi)服務(wù)端認(rèn)可的票據(jù)。也就是說(shuō),客戶端在訪問(wèn)服務(wù)器之前需要預(yù)先買(mǎi)好票,等待服務(wù)驗(yàn)票之后才能入場(chǎng)。在這之前,客戶端需要先買(mǎi)票,但是這張票不能直接購(gòu)買(mǎi),需要一張認(rèn)購(gòu)權(quán)證。客戶端在買(mǎi)票之前需要預(yù)先獲得一張認(rèn)購(gòu)權(quán)證。這張認(rèn)購(gòu)權(quán)證和進(jìn)入服務(wù)器的入場(chǎng)券均有KDC發(fā)售。右圖(點(diǎn)擊看大圖)一張圖基本揭示了Kerberos整個(gè)認(rèn)證的過(guò)程。
二、如何獲得“認(rèn)購(gòu)權(quán)證”?

首先,我們來(lái)看看客戶端如何獲得“認(rèn)購(gòu)權(quán)證”。這里的認(rèn)購(gòu)權(quán)證有個(gè)專(zhuān)有的名稱(chēng)——TGT(Ticket Granting Ticket),而TGT的是KDC一個(gè)重要的服務(wù)——認(rèn)證服務(wù)(KAS:Kerberos Authentication Service)。當(dāng)某個(gè)用戶通過(guò)輸入域帳號(hào)和密碼試圖登錄某臺(tái)主機(jī)的時(shí)候,本機(jī)的Kerberos服務(wù)會(huì)向KDC的認(rèn)證服務(wù)發(fā)送一個(gè)認(rèn)證請(qǐng)求。該請(qǐng)求主要包括兩部分內(nèi)容,明文形式的用戶名和經(jīng)過(guò)加密的用于證明訪問(wèn)者身份的Authenticator(我實(shí)在找不到一個(gè)比較貼切的中文翻譯沒(méi),Authenticator在這里可以理解為僅限于驗(yàn)證雙反預(yù)先知曉的內(nèi)容,相當(dāng)于聯(lián)絡(luò)暗號(hào))。
當(dāng)KDC接收到請(qǐng)求之后,通過(guò)AD獲取該用戶的信息。通過(guò)獲取的密碼信息生成一個(gè)秘鑰對(duì)Authenticator進(jìn)行解密。如果解密后的內(nèi)容和已知的內(nèi)容一致,則證明請(qǐng)求著提供的密碼正確,即確定了登錄者的真實(shí)身份。
KAS成功認(rèn)證對(duì)方的身份之后,會(huì)先生成一個(gè)用于確保該用戶和KDC之間通信安全的會(huì)話秘鑰——Logon Session Key,并采用該用戶密碼派生的秘鑰進(jìn)行加密。KAS接著為該用戶創(chuàng)建“認(rèn)購(gòu)權(quán)證”——TGT。TGT主要包含兩方面的內(nèi)容:用戶相關(guān)信息和Logon Session Key,而整個(gè)TGT則通過(guò)KDC自己的密鑰進(jìn)行加密。最終,被不同密鑰加密的Logon Session Key和TGT返回給客戶端。(以上的內(nèi)容對(duì)應(yīng)流程圖中的步驟1、2)
三、如何通過(guò)“認(rèn)購(gòu)權(quán)證”購(gòu)買(mǎi)“入場(chǎng)券”?

經(jīng)過(guò)上面的步驟,客戶端獲取了購(gòu)買(mǎi)進(jìn)入同域中其他主機(jī)入場(chǎng)券的“認(rèn)購(gòu)憑證”——TGT,以及Logon Session Key,它會(huì)在本地緩存此TGT和Logon Session Key。如果現(xiàn)在它需要訪問(wèn)某臺(tái)服務(wù)器的資源,它就需要憑借這張TGT向KDC購(gòu)買(mǎi)相應(yīng)的入場(chǎng)券。這里的入場(chǎng)券也有一個(gè)專(zhuān)有的名稱(chēng)——服務(wù)票據(jù)(ST:Service Ticket)。
具體來(lái)說(shuō),ST是通過(guò)KDC的另一個(gè)服務(wù)TGS(Ticket Granting Service)出售的。客戶端先向TGS發(fā)送一個(gè)ST購(gòu)買(mǎi)請(qǐng)求,該請(qǐng)求主要包含如下的內(nèi)容:客戶端用戶名;通過(guò)Logon Session Key加密的Authenticator;TGT和訪問(wèn)的服務(wù)器(其實(shí)是服務(wù))名。
TGS接收到請(qǐng)求之后,現(xiàn)通過(guò)自己的密鑰解密TGT并獲取Logon Session Key,然后通過(guò)Logon Session Key解密Authenticator,進(jìn)而驗(yàn)證了對(duì)方的真實(shí)身份。
TGS存在的一個(gè)根本的目有兩點(diǎn):其一是避免讓用戶的密碼客戶端和KDC之間頻繁傳輸而被竊取。其二是因?yàn)槊艽a屬于Long Term Key(我們一般不會(huì)頻繁的更新自己的密碼),讓它作為加密密鑰的安全系數(shù)肯定小于一個(gè)頻繁變換得密鑰(Short Term Key)。而這個(gè)Short Term Key就是Logon Session Key,它確保了客戶端和KDC之間的通信安全。
TGS完成對(duì)客戶端的認(rèn)證之后,會(huì)生成一個(gè)用于確保客戶端-服務(wù)器之間通信安全的會(huì)話秘鑰——Service Session Key,該會(huì)話秘鑰通過(guò)Logon Session Key進(jìn)行加密。然后出售給客戶端需要的入場(chǎng)券——ST。ST主要包含兩方面的內(nèi)容:客戶端用戶信息和Service Session Key,整個(gè)ST通過(guò)服務(wù)器密碼派生的秘鑰進(jìn)行加密。最終兩個(gè)被加密的Service Session Key和ST回復(fù)給客戶端。(以上的內(nèi)容對(duì)應(yīng)流程圖中的步驟3、4)
四、憑票入場(chǎng)

客戶端接收到TGS回復(fù)后,通過(guò)緩存的Logon Session Key解密獲取Service Session Key。同時(shí)它也得到了進(jìn)入服務(wù)器的入場(chǎng)券——ST。那么它在進(jìn)行服務(wù)訪問(wèn)的時(shí)候就可以借助這張ST憑票入場(chǎng)了。該Serivce Session Key和ST會(huì)被客戶端緩存。
但是,服務(wù)端在接收到ST之后,如何確保它是通過(guò)TGS購(gòu)買(mǎi),而不是自己偽造的呢?這很好辦,不要忘了ST是通過(guò)自己密碼派生的秘鑰進(jìn)行加密的。具體的操作過(guò)程是這樣的,除了ST之外,服務(wù)請(qǐng)求還附加一份通過(guò)Service Session Key加密的Authenticator。服務(wù)器在接收到請(qǐng)求之后,先通過(guò)自己密碼派生的秘鑰解密ST,并從中提取Service Session Key。然后通過(guò)提取出來(lái)的Service Session Key解密Authenticator,進(jìn)而驗(yàn)證了客戶端的真實(shí)身份。
實(shí)際上,到目前為止,服務(wù)端已經(jīng)完成了對(duì)客戶端的驗(yàn)證,但是,整個(gè)認(rèn)證過(guò)程還沒(méi)有結(jié)束。談到認(rèn)證,很多人都認(rèn)為只是服務(wù)器對(duì)客戶端的認(rèn)證,實(shí)際上在大部分場(chǎng)合,我們需要的是雙向驗(yàn)證(Mutual Authentication)——訪問(wèn)者和被訪問(wèn)者互相驗(yàn)證對(duì)方的身份。現(xiàn)在服務(wù)器已經(jīng)可以確保客戶端是它所聲稱(chēng)的那么用戶,客戶端還沒(méi)有確認(rèn)它所訪問(wèn)的不是一個(gè)釣魚(yú)服務(wù)呢。
為了解決客戶端對(duì)服務(wù)器的驗(yàn)證,服務(wù)要需要將解密后的Authenticator再次用Service Session Key進(jìn)行加密,并發(fā)揮給客戶端。客戶端再用緩存的Service Session Key進(jìn)行解密,如果和之前的內(nèi)容完全一樣,則可以證明自己正在訪問(wèn)的服務(wù)器和自己擁有相同的Service Session Key,而這個(gè)會(huì)話秘鑰不為外人知曉(以上的內(nèi)容對(duì)應(yīng)流程圖中的步驟5、6)
以上的內(nèi)容僅僅講述的是基于Kerberos的Windows認(rèn)證的大體流程,并不涉及到一些細(xì)節(jié)的東西,比如如何確保時(shí)間的同步,如何抵御Replay Attack等。此外,由于本文對(duì)Windows底層的知識(shí)有限,不能確保所有的內(nèi)容都是完全正確,如有錯(cuò)誤,還往不吝指正。