Client通过自己的Master Key对第一部分解密获得Session Key(SKDC-Client:Logon Session Key)之后,携带着TGT便可以进入下一步:TGS(TicketGranting Service)Exchange。
2. TGS(TicketGranting Service)Exchange
TGS(Ticket Granting Service)Exchange通过Client向KDC中的TGS(Ticket Granting Service)发送Ticket Granting Service Request(KRB_TGS_REQ)开始。KRB_TGS_REQ大体包含以下的内容:
TGT:Client通过ASExchange获得的Ticket Granting Ticket,TGT被KDC的Master Key进行加密。
Authenticator:用以证明当初TGT的拥有者是否就是自己,所以它必须以TGT的办法方和自己的Session Key(SKDC-Client:Logon Session Key)来进行加密。
Client name& realm: 简单地说就是Domain name\Client。
Server name& realm: 简单地说就是Domain name\Server,这回是Client试图访问的那个Server。
TGS收到KRB_TGS_REQ在发给Client真正的Ticket之前,先得整个Client提供的那个TGT是否是AS颁发给它的。于是它不得不通过Client提供的Authenticator来证明。但是Authentication是通过LogonSession Key(SKDC-Client)进行加密的,而自己并没有保存这个Session Key。所以TGS先得通过自己的Master Key对Client提供的TGT进行解密,从而获得这个Logon Session Key(SKDC-Client),再通过这个Logon Session Key(SKDC-Client)解密Authenticator进行验证。验证通过向对方发送Ticket Granting Service Response(KRB_TGS_REP)。这个KRB_TGS_REP有两部分组成:使用Logon Session Key(SKDC-Client)加密过用于Client和Server的Session Key(SServer-Client)和使用Server的MasterKey进行加密的Ticket。该Ticket大体包含以下一些内容:
Session Key:SServer-Client。
Client name& realm: 简单地说就是Domain name\Client。
End time:Ticket的到期时间。
Client收到KRB_TGS_REP,使用LogonSession Key(SKDC-Client)解密第一部分后获得Session Key(SServer-Client)。有了Session Key和Ticket,Client就可以之间和Server进行交互,而无须在通过KDC作中间人了。所以我们说Kerberos是一种高效的认证方式,它可以直接通过Client和Server双方来完成,不像Windows NT 4下的NTLM认证方式,每次认证都要通过一个双方信任的第3方来完成。
我们现在来看看 Client如果使用Ticket和Server怎样进行交互的,这个阶段通过我们的第3个Sub-protocol来完成:CS(Client/Server)Exchange。
3. CS(Client/Server)Exchange
这个已经在本文的第二节中已经介绍过,对于重复发内容就不再累赘了。Client通过TGSExchange获得Client和Server的Session Key(SServer-Client),随后创建用于证明自己就是Ticket的真正所有者的Authenticator,并使用SessionKey(SServer-Client)进行加密。最后将这个被加密过的Authenticator和Ticket作为Application Service Request(KRB_AP_REQ)发送给Server。除了上述两项内容之外,KRB_AP_REQ还包含一个Flag用于表示Client是否需要进行双向验证(Mutual Authentication)。
Server接收到KRB_AP_REQ之后,通过自己的Master Key解密Ticket,从而获得Session Key(SServer-Client)。通过Session Key(SServer-Client)解密Authenticator,进而验证对方的身份。验证成功,让Client访问需要访问的资源,否则直接拒绝对方的请求。
对于需要进行双向验证,Server从Authenticator提取Timestamp,使用SessionKey(SServer-Client)进行加密,并将其发送给Client用于Client验证Server的身份。
User to user子过程
通过3个Sub-protocol的介绍,我们可以全面地掌握整个Kerberos的认证过程。实际上,在Windows 2000时代,基于Kerberos的WindowsAuthentication就是按照这样的工作流程来进行的。但是我在上面一节结束的时候也说了,基于3个Sub-protocol的Kerberos作为一种NetworkAuthentication是具有它自己的局限和安全隐患的。我在整篇文章一直在强调这样的一个原则:以某个Entity的Long-termKey加密的数据不应该在网络中传递。原因很简单,所有的加密算法都不能保证100%的安全,对加密的数据进行解密只是一个时间的过程,最大限度地提供安全保障的做法就是:使用一个Short-term key(SessionKey)代替Long-term Key对数据进行加密,使得恶意用户对其解密获得加密的Key时,该Key早已失效。但是对于3个Sub-Protocol的C/S Exchange,Client携带的Ticket却是被ServerMaster Key进行加密的,这显现不符合我们提出的原则,降低Server的安全系数。
所以我们必须寻求一种解决方案来解决上面的问题。这个解决方案很明显:就是采用一个Short-term的SessionKey,而不是Server Master Key对Ticket进行加密。这就是我们今天要介绍的Kerberos的第4个Sub-protocol:User2UserProtocol。我们知道,既然是Session Key,仅必然涉及到两方,而在Kerberos整个认证过程涉及到3方:Client、Server和KDC,所以用于加密Ticket的只可能是Server和KDC之间的Session Key(SKDC-Server)。