Kerberos Authentication 解决的是“如何证明某个用户确确实实就是其所声称的那个用户”的问题。
Kerberos Authentication的整个过程涉及到Client和Server,他们之间传递证明需要使用一个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,所以对方就是其所声称的那用户。
在讨论Client和Server如何得到KServer-Client前,我们需要引入一个重要的角色:Kerberos Distribution Center-KDC。
KDC在整个Kerberos Authentication中作为Client和Server共同信任的第三方起着重要的作用,而Kerberos的认证过程就是通过这3方协作完成。Kerberos起源于希腊神话,是一条守护着冥界长着3个头颅的神犬,在keberos Authentication中,Kerberos的3个头颅代表中认证过程中涉及的3方:Client、Server和KDC,kerberos因此得名 。
在详细介绍Kerberos Authentication 之前我们先引入两个重要概念:
Long-term Key/Master Key:在Security的领域中,有的Key可能长期内保持不变,比如你在密码,可能几年都不曾改变,这样的Key、以及由此派生的Key被称为Long-term Key。对于Long-term Key的使用有这样的原则:被Long-term Key加密的数据不应该在网络上传输。
原因很简单,一旦这些被Long-term Key加密的数据包被恶意的网络监听者截获,理论上只要有充足的时间,他是可以通过计算获得你用于加密的Long-term Key的。
Short-term Key/Session Key:由于被Long-term Key加密的数据包不能用于网络传送,所以我们使用另一种Short-term Key来加密需要进行网络传输的数据。
由于这种Key只在一段时间内有效,即使被加密的数据包被黑客截获,等他把Key计算出来的时候,这个Key早就已经过期了。
通过下图我们可以看到KDC分发KServer-Client的简单的过程:
①Client A向KDC发送一个对SServer-Client的申请。这个申请的内容可以简单概括为“我是Client A,我需要一个Session Key用于访问Server A ”。
②KDC接收到这个请求后,生成一个Session Key。
③为了保证这个Session Key仅仅限于发送请求的Client A和他希望访问的Server A知晓,KDC会为这个Session Key生成两个Copy,分别被Client A和Server A使用。
④KDC从Account database中提取Client A和Server A的Master Key分别对这两个Copy进行对称加密。其中被SAMaster key加密的Session Key会和关于Client A的一些信息一起被加密。
⑤KDC将被加密后的Session Ticket和C Session Key一起发送给Client A。
a.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将永远得不到认证。
b.如果Client B声称自己是Client A,KDC依然会使用Client A的Password派生的Master Key对Session Key进行加密,所以只有真正持有Client A 的Password的一方才会通过解密获得Session Key,其他用户无法冒充。
通过KServer-Client后,Client A获得了两组信息:
①通过CA Master Key加密的C Session Key.
②通过SA Master Key加密的,包含Client A信息的Session
Ticket
在一个真实网络的环境中,仅使用以上两项进行认证是存在安全漏洞的,为此Client需要提供更多的证明信息,我们把这种证明信息称为Authenticator,在Kerberos的Authenticator实际上就是关于Client的一些信息(Client Info)和当前时间(Timestamp)。
通过下图我们可以看到Server如何对Client进行认证:
①Client A通过自己的CA Master Key对KDC加密的C Session Key进行解密从而获得Session Key(SServer-Client)。
②创建Authenticator(Client Info + Timestamp)。
③用Session Key(SServer-Client)对Authenticator加密。
④连同从KDC获得的、被Server的Master Key加密过的Session Ticket(Client Info + Session Key)一并发送给Server A。
⑤Server A接收到这两组数据后,先使用他自己的SA Master Key对Session Ticket进行解密,从而获得Session Key(SServer-Client)和Client A Info。
⑥Server A使用Session Key(SServer-Client)解密Authenticator,从而获得Timestamp和Client A Info。
⑦KDC将从Authenticator中解密出的Timestamp与现在的Timestamp比较,如果时间超过5分钟(默认)则拒绝对Client A进行认证。
⑧KDC对比从Authenticator中解密出的Client A Info和从Session Ticket中解密出Client A Info,如果相同,那么就实现了Client A的认证
Kerberos一个重要的优势在于它能够提供双向认证:不但Server可以对Client 进行认证,Client也能对Server进行认证。
在Authentication的基础上查看下图:
⑨Server A在对Client A认证成功之后,会把Authenticator中的Timestamp提出出来,通过Session Key(SServer-Client)进行加密,并发送给Client A。
⑩Client A将解密后获得的Timestamp与自己生成的Timestamp进行比较,如果相同则Client 就会认证Server A
a.为什么要使用Timestamp?
我们试想这样的现象:Client向Server发送的数据包被某个恶意网络监听者截获,该监听者随后将数据包作为自己的Authenticator冒充该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采用进行后续的认证流程。
b。双向认证时,为什么Server不直接把通过Session Key进行加密的Authenticator原样发送给Client,而要把Timestamp提取出来加密发送给Client呢?
防止恶意的监听者通过获取的Client发送的Authenticator冒充Server获得Client的认证
通过上面的介绍,我们发现Kerberos实际上一个基于Ticket的认证方式。Client想要获取Server端的资源,先得通过Server的认证;而认证的先决条件是Client向Server提供从KDC获得的一个有S Master Key进行加密的Session Ticket(Session Key + Client Info)。可以这么说,Session Ticket是Client进入Server领域的一张门票。而这张门票必须从一个合法的Ticket颁发机构获得,这个颁发机构就是Client和Server双方信任的KDC, 同时这张Ticket具有超强的防伪标识:它是被Server的Master Key加密的。对Client来说, 获得Session Ticket是整个认证过程中最为关键的部分,这就是KDC向Client分发Ticket的基本过程。
这个认证凭证我们成为TGT,通过下图我们了解一下Client是如何从KDC处获得TGT:
①Client向KDC发起对TGT的申请,申请的内容大致可以这样表示:“我需要一张TGT用以申请获取用以访问所有Server的Ticket”。
②KDC在收到申请请求后,生成一个用于该Client和KDC进行安全通信的Session Key(SKDC-Client)。
③KDC使用CA Master Key对Session Key(SKDC-Client)进行加密生成SKDC-Client,使用KDC Master Key对Session Key(SKDC-Client)进行加密,其中包含以后用于鉴定Client身份的关于Client的一些信息。这两份都称为SKDC-Client的Copy
④KDC将这两份Copy一并发送给Client。这里有一点需要注意的是:为了免去KDC对于基于不同Client的Session Key进行维护的麻烦,就像Server不会保存Session Key(SServer-Client)一样,KDC也不会去保存这个Session Key(SKDC-Client),而选择完全靠Client自己提供的方式。
⑤当Client收到KDC的两个加密数据包之后,先使用自己的CA Master Key对第一个Copy进行解密,从而获得KDC和Client的Session Key(SKDC-Client),并把该Session 和TGT进行缓存。
有了Session Key和TGT后,Client自己的Master Key将不再需要,因为此后Client可以使用SKDC-Client向KDC申请用以访问每个Server的Ticket,相对于Client的Master Key这个Long-term Key,SKDC-Client是一个Short-term Key,安全保证得到更好的保障,这也是Kerberos多了这一步的关键所在。同时需要注意的是SKDC-Client是一个Session Key,他具有自己的生命周期,同时TGT和Session相互关联,当Session Key过期,TGT也就宣告失效,此后Client不得不重新向KDC申请新的TGT,KDC将会生成一个不同Session Key和与之关联的TGT。同时,由于Client Log off也导致SKDC-Client的失效,所以SKDC-Client又被称为Logon Session Key。
通过下图我们来了解一下Client如何使用TGT从KDC获得目标Server的Ticket:
①Client A在获得自己和KDC的Session Key(SKDC-Client)之后,生成自己的Authenticator以及所要访问的Server名称(Server Name)
②Client A使用Session Key(SKDC-Client)加密Authenticator和Server Name。
③Client A将加密数据包和TGT一起发送给KDC
④KDC使用自己的KDC Master Key对TGT进行解密,获得Client A Info和Session Key(SKDC-Client).
⑤KDC使用Session Key(SKDC-Client)解密加密数据包获得Authenticator和Server Name。
⑥KDC使用Session Key(SKDC-Client)解密Authenticator获得Client A Info和Timestamp。
⑦KDC将从Authenticator中解密出的Timestamp与现在的Timestamp比较,如果时间超过5分钟(默认)则拒绝对Client A进行认证。
⑧KDC对比从Authenticator中解密出的Client A Info和从TGT 中解密出Client A Info,如果相同,那么就实现了Client A的认证。
⑨认证成功后,KDC将Session Ticket发送给Client。
Ticket是基于某个具体的Server的,而TGT则是和具体的Server无关的,Client可以使用一个TGT从KDC获得基于不同Server的Ticket。
通过以上的介绍,我们基本上了解了整个Kerberos authentication的整个流程:整个流程大体上包含以下3个子过程:
①Client向KDC申请TGT(Ticket Granting Ticket)。
②Client通过获得TGT向DKC申请用于访问Server的Ticket。
③Client最终向为了Server对自己的认证向其提交Ticket。
不过上面的介绍离真正的Kerberos Authentication还是有一点出入。Kerberos整个认证过程通过3个sub-protocol来完成。这个3个Sub-Protocol分别完成上面列出的3个子过程。这3个sub-protocol分别为:
①Authentication Service Exchange
②Ticket Granting Service Exchange
③Client/Server Exchange
下图简单展示了完成这个3个Sub-protocol如何进行Message Exchange。
通过这个Sub-protocol,KDC(确切地说是KDC中的Authentication Service)实现对Client身份的确认,并颁发给该Client一个TGT。具体过程如下图:
①Client A创建Server Name、Client name & realm,用CA Master Key加密Client A Info和Timestamp生成Pre-authentication data。
①Client A创建Client name & realm、Server name & realm、使用Session Key(SKDC-Client)加密Client A Info生成Authenticator。
②Client A将Client name & realm、Server name & realm、Authenticator、TGT生成Ticket Granting Service Request(KRB_TGS_REQ)。
③Client A将KRB_TGS_REQ发送给KDC。
④KDC收到数据后使用KDC Master Key解密TGT获得Session(SKDC-Client)和Client A Info。
⑤KDC使用Session Key(SKDC-Client)解密Authenticator获得Client A Info。
⑥KDC对比从Authenticator中解密出的Client A Info和从TGT Ticket中解密出Client A Info,如果相同,那么就实现了Client A的认证。
⑦KDC生成Session Key(SServer-Client)和End Time,然后使用SA Master Key加密Session Key(SServer-Client)、End Time、Client name & realm生成Session Ticket。与此同时使用Session Key(SServer-Client)加密Session Key(SKDC-Client)。最后用加密后的Session Key(SKDC-Client)和Session Ticket生成KRB_TGS_REP。
⑧KDC将KRB_TGS_REP发送给Client A。
①Client A使用CA Master Key解密Session Key(SKDC-Client)得到Session Key(SServer-Client)。
②Client A使用Sesion Ticket加密Client A Info和Timestamp生成Authenticator用于证明自己就是Ticket的真正所有者。
③Client A使用Session Key(SServer-Client)加密Authenticator。
④Client A将被加密的Authenticator和Session Ticket生成KRB_AP_REQ并发送给Server A。
⑤Server A收到数据后使用SA Master Key解密Session Ticket获得Session Key(SServer-Client)和Client A Info。
⑥Server A使用Session Key(SServer-Client)解密Authenticator获得Timestamp和Client A Info。
⑦Server A将从Authenticator中解密出的Timestamp与现在的Timestamp比较,如果时间超过5分钟(默认)则拒绝对Client A进行认证。
⑧Server A对比从Authenticator中解密出的Client A Info和从Session Ticket中解密出Client A Info,如果相同,那么就实现了Client A的认证。
⑨认证成功后,Server A生成KRB_AP_REP并发送给Client A。
在CS Exchange(单项)基础上
⑨Server A在对Client A认证成功之后,会把Authenticator中的Timestamp提出出来,通过Session Key(SServer-Client)进行加密,并发送给Client A。
⑩Server A生成KRB_AP_REP并发送给Client A,Client A将解密后获得的Timestamp与自己生成的Timestamp进行比较,如果相同则Client A就会认证Server A。
User2User Sub-Protocol可以有效班长Server的安全。
我们知道Client通过在AS Exchange阶段获得的TGT从KDC那么获得访问Server的Ticket。原来的Ticket是通过Server的Master Key进行加密的,而这个Master Key可以通过Account Database获得。但是现在KDC需要使用Server和KDC之间的SKDC-Server进行加密,而KDC是不会维护这个Session Key,所以这个Session Key只能靠申请Ticket的Client提供。所以在AS Exchange和TGS Exchange之间,Client还得对Server进行请求已获得Server和KDC之间的Session Key(SKDC-Server)。而对于Server来说,它可以像Client一样通过AS Exchange获得他和KDC之间的Session Key(SKDC-Server)和一个封装了这个Session Key并被KDC的Master Key进行加密的TGT,一旦获得这个TGT,Server会缓存它,以待Client对它的请求。我们现在来详细地讨论这一过程。
通过上图我们了解到这个过程由4个步骤组成,让我们从头到尾简单地了解一遍:
参考文献
kerberos认证原理—讲的非常细致,易懂