天天看點

談談基于Kerberos的Windows Network Authentication[上篇]

Content:

基本原理

引入Key Distribution: KServer-Client從何而來

引入Authenticator : 為有效的證明自己提供證據

引入Ticket Granting  Service:如何獲得Ticket

Kerberos的3個Sub-protocol:整個Authentication的流程

User2User Protocol: 有效地保障Server的安全

Kerberos的優點的優點

前幾天在給人解釋Windows是如何通過Kerberos進行Authentication的時候,講了半天也别把那位老兄講明白,還差點把自己給繞進去。後來想想原因有以下兩點:對于一個沒有完全不了解Kerberos的人來說,Kerberos的整個Authentication過程确實不好了解——一會兒以這個Key進行加密、一會兒又要以另一個Key進行加密,确實很容易把人給弄暈;另一方面是我講解方式有問題,一開始就從Kerberos的3個Sub-protocol全面講述整個Authentication

過程,對于一個完全不了解Kerberos的人來說要求也忒高了點。為此,我花了一些時間寫了這篇文章,盡量以由淺入深、層層深入的方式講述我所了解的基于Kerberos的Windows

Network

Authentication,希望這篇文章能幫助那些對Kerberos不明就裡的人帶來一絲幫助。對于一些不對的地方,歡迎大家批評指正。

一、 基本原理

Authentication解決的是“如何證明某個人确确實實就是他或她所聲稱的那個人”的問題。對于如何進行Authentication,我們采用這樣的方法:如果一個秘密(secret)僅僅存在于A和B,那麼有個人對B聲稱自己就是A,B通過讓A提供這個秘密來證明這個人就是他或她所聲稱的A。這個過程實際上涉及到3個重要的關于Authentication的方面:

Secret如何表示。

A如何向B提供Secret。

B如何識别Secret。

基于這3個方面,我們把Kerberos Authentication進行最大限度的簡化:整個過程涉及到Client和Server,他們之間的這個Secret我們用一個Key(KServer-Client)來表示。Client為了讓Server對自己進行有效的認證,向對方提供如下兩組資訊:

代表Client自身Identity的資訊,為了簡便,它以明文的形式傳遞。

将Client的Identity使用KServer-Client作為Public Key、并采用對稱加密算法進行加密。

由于KServer-Client僅僅被Client和Server知曉,是以被Client使用KServer-Client加密過的Client Identity隻能被Client和Server解密。同理,Server接收到Client傳送的這兩組資訊,先通過KServer-Client對後者進行解密,随後将機密的資料同前者進行比較,如果完全一樣,則可以證明Client能過提供正确的KServer-Client,而這個世界上,僅僅隻有真正的Client和自己知道KServer-Client,是以可以對方就是他所聲稱的那個人。

Keberos大體上就是按照這樣的一個原理來進行Authentication的。但是Kerberos遠比這個複雜,我将在後續的章節中不斷地擴充這個過程,知道Kerberos真實的認證過程。為了使讀者更加容易了解後續的部分,在這裡我們先給出兩個重要的概念:

Long-term Key/Master Key:在Security的領域中,有的Key可能長期内保持不變,比如你在密碼,可能幾年都不曾改變,這樣的Key、以及由此派生的Key被稱為Long-term

Key。對于Long-term Key的使用有這樣的原則:被Long-term

Key加密的資料不應該在網絡上傳輸。原因很簡單,一旦這些被Long-term

Key加密的資料包被惡意的網絡監聽者截獲,在原則上,隻要有充足的時間,他是可以通過計算獲得你用于加密的Long-term

Key的——任何加密算法都不可能做到絕對保密。

在一般情況下,對于一個Account來說,密碼往往僅僅限于該Account的所有者知曉,甚至對于任何Domain的Administrator,密碼仍然應該是保密的。但是密碼卻又是證明身份的憑據,是以必須通過基于你密碼的派生的資訊來證明使用者的真實身份,在這種情況下,一般将你的密碼進行Hash運算得到一個Hash

code, 我們一般管這樣的Hash Code叫做Master Key。由于Hash Algorithm是不可逆的,同時保證密碼和Master

Key是一一對應的,這樣既保證了你密碼的保密性,有同時保證你的Master Key和密碼本身在證明你身份的時候具有相同的效力。

Short-term Key/Session Key:由于被Long-term

Key加密的資料包不能用于網絡傳送,是以我們使用另一種Short-term

Key來加密需要進行網絡傳輸的資料。由于這種Key隻在一段時間内有效,即使被加密的資料包被黑客截獲,等他把Key計算出來的時候,這個Key早就已經過期了。

二、引入Key Distribution: KServer-Client從何而來

上面我們讨論了Kerberos Authentication的基本原理:通過讓被認證的一方提供一個僅限于他和認證方知曉的Key來鑒定對方的真實身份。而被這個Key加密的資料包需要在Client和Server之間傳送,是以這個Key不能是一個Long-term Key,而隻可能是Short-term Key,這個可以僅僅在Client和Server的一個Session中有效,是以我們稱這個Key為Client和Server之間的Session Key(SServer-Client)。

現在我們來讨論Client和Server如何得到這個SServer-Client。在這裡我們要引入一個重要的角色:Kerberos Distribution Center-KDC。KDC在整個Kerberos

Authentication中作為Client和Server共同信任的第三方起着重要的作用,而Kerberos的認證過程就是通過這3方協作完成。順便說一下,Kerberos起源于希臘神話,是一支守護着冥界長着3個頭顱的神犬,在keberos

Authentication中,Kerberos的3個頭顱代表中認證過程中涉及的3方:Client、Server和KDC。

對于一個Windows Domain來說,Domain Controller扮演着KDC的角色。KDC維護着一個存儲着該Domain中所有帳戶的Account Database(一般地,這個Account Database由AD來維護),也就是說,他知道屬于每個Account的名稱和派生于該Account Password的Master Key。而用于Client和Server互相認證的SServer-Client就是有KDC分發。下面我們來看看KDC分發SServer-Client的過程。

通過下圖我們可以看到KDC分發SServer-Client的簡單的過程:首先Client向KDC發送一個對SServer-Client的申請。這個申請的内容可以簡單概括為“我是某個Client,我需要一個Session Key用于通路某個Server

”。KDC在接收到這個請求的時候,生成一個Session Key,為了保證這個Session

Key僅僅限于發送請求的Client和他希望通路的Server知曉,KDC會為這個Session

Key生成兩個Copy,分别被Client和Server使用。然後從Account

database中提取Client和Server的Master Key分别對這兩個Copy進行對稱加密。對于後者,和Session

Key一起被加密的還包含關于Client的一些資訊。

KDC現在有了兩個分别被Client和Server

的Master Key加密過的Session Key,這兩個Session Key如何分别被Client和Server獲得呢?也許你

馬上會說,KDC直接将這兩個加密過的包發送給Client和Server不就可以了嗎,但是如果這樣做,對于Server來說會出現下面 兩個問題:

由于一個Server會面對若幹不同的Client, 而每個Client都具有一個不同的Session Key。那麼Server就會為所有的Client維護這樣一個Session Key的清單,這樣做對于Server來說是比較麻煩而低效的。

由于網絡傳輸的不确定性,可能出現這樣一種情況:Client很快獲得Session

Key,并将這個Session Key作為Credential随同通路請求發送到Server,但是用于Server的Session

Key确還沒有收到,并且很有可能承載這個Session Key的永遠也到不了Server端,Client将永遠得不到認證。

為了解決這個問題,Kerberos的做法很簡單,将這兩個被加密的Copy一并發送給Client,屬于Server的那份由Client發送給Server。

可能有人會問,KDC并沒有真正去認證這個發送請求的Client是否真的就是那個他所聲稱的那個人,就把Session

Key發送給他,會不會有什麼問題?如果另一個人(比如Client B)聲稱自己是Client A,他同樣會得到Client

A和Server的Session Key,這會不會有什麼問題?實際上不存在問題,因為Client B聲稱自己是Client

A,KDC就會使用Client A的Password派生的Master Key對Session Key進行加密,是以真正知道Client A

的Password的一方才會通過解密獲得Session Key。 

三、引入Authenticator - 為有效的證明自己提供證據

通過上面的過程,Client實際上獲得了兩組資訊:一個通過自己Master

Key加密的Session Key,另一個被Sever的Master Key加密的資料包,包含Session

Key和關于自己的一些确認資訊。通過第一節,我們說隻要通過一個雙方知曉的Key就可以對對方進行有效的認證,但是在一個網絡的環境中,這種簡單的做法是具有安全漏洞,為此,Client需要提供更多的證明資訊,我們把這種證明資訊稱為Authenticator,在Kerberos的Authenticator實際上就是關于Client的一些資訊和目前時間的一個Timestamp(關于這個安全漏洞和Timestamp的作用,我将在後面解釋)。

在這個基礎上,我們再來看看Server如何對Client進行認證:Client通過自己的Master Key對KDC加密的Session Key進行解密進而獲得Session Key,随後建立Authenticator(Client Info + Timestamp)并用Session Key對其加密。最後連同從KDC獲得的、被Server的Master Key加密過的資料包(Client Info + Session Key)一并發送到Server端。我們把通過Server的Master Key加密過的資料包稱為Session Ticket。

當Server接收到這兩組資料後,先使用他自己的Master Key對Session Ticket進行解密,進而獲得Session Key。随後使用該Session Key解密Authenticator,通過比較Authenticator中的Client Info和Session Ticket中的Client Info進而實作對Client的認證。

為什麼要使用Timestamp?

到這裡,很多人可能認為這樣的認證過程天衣無縫:隻有當Client提供正确的Session Key方能得到Server的認證。但是在現實環境中,這存在很大的安全漏洞。

我們試想這樣的現象:Client向Server發送的資料包被某個惡意網絡監聽者截獲,該監聽者随後将資料包座位自己的Credential冒充該Client對Server進行通路,在這種情況下,依然可以很順利地獲得Server的成功認證。為了解決這個問題,Client在Authenticator中會加入一個目前時間的Timestamp。

在Server對Authenticator中的Client Info和Session Ticket中的Client Info進行比較之前,會先提取Authenticator中的Timestamp,并同目前的時間進行比較,如果他們之間的偏差超出一個可以接受的時間範圍(一般是5mins),Server會直接拒絕該Client的請求。在這裡需要知道的是,Server維護着一個清單,這個清單記錄着在這個可接受的時間範圍内所有進行認證的Client和認證的時間。對于時間偏差在這個可接受的範圍中的Client,Server會從這個這個清單中獲得最近一個該Client的認證時間,隻有當Authenticator中的Timestamp晚于通過一個Client的最近的認證時間的情況下,Server采用進行後續的認證流程。

Time Synchronization的重要性

上述 基于Timestamp的認證機制隻有在Client和Server端的時間保持同步的情況才有意義。是以保持Time Synchronization在整個認證過程中顯得尤為重要。在一個Domain中,一般通過通路同一個Time Service獲得目前時間的方式來實作時間的同步。

雙向認證(Mutual Authentication)

Kerberos一個重要的優勢在于它能夠提供雙向認證:不但Server可以對Client 進行認證,Client也能對Server進行認證。

具體過程是這樣的,如果Client需要對他通路的Server進行認證,會在它向Server發送的Credential中設定一個是否需要認證的Flag。Server在對Client認證成功之後,會把Authenticator中的Timestamp提出出來,通過Session

Key進行加密,當Client接收到并使用Session Key進行解密之後,如果确認Timestamp和原來的完全一緻,那麼他可以認定Server正式他試圖通路的Server。

那麼為什麼Server不直接把通過Session

Key進行加密的Authenticator原樣發送給Client,而要把Timestamp提取出來加密發送給Client呢?原因在于防止惡意的監聽者通過擷取的Client發送的Authenticator冒充Server獲得Client的認證。

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/07/809545.html">談談基于Kerberos的Windows Network Authentication - Part II</a>

相關内容:

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/05/807492.html">[原創]談談基于Kerberos的Windows Network Authentication - Part I</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/07/809545.html">[原創]談談基于Kerberos的Windows Network Authentication - Part II</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/10/811970.html">[原創]談談基于Kerberos的Windows Network Authentication - Part III</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2007/07/05/807492.html" target="_blank">原文連結</a>

繼續閱讀