谈谈基于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 InfoSession 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的认证。


谈谈基于Kerberos的Windows Network Authentication - Part II

相关内容:
[原创]谈谈基于Kerberos的Windows Network Authentication - Part I
[原创]谈谈基于Kerberos的Windows Network Authentication - Part II
[原创]谈谈基于Kerberos的Windows Network Authentication - Part III

posted @ 2007-07-05 18:44 Artech 阅读(5865) 评论(38) 编辑 收藏

 回复 引用   
#1楼 2007-07-05 18:51 路过的[未注册用户]
精彩,期待后续!
 回复 引用   
#2楼 2007-07-05 18:52 专注BI[未注册用户]
精品, 讲的很清楚
 回复 引用 查看   
#3楼[楼主] 2007-07-05 19:13 Artech      
@路过的
@专注BI
谢谢两位的光临!

 回复 引用 查看   
#4楼 2007-07-05 19:18 Cheney Shue      
Great
 回复 引用 查看   
#5楼[楼主] 2007-07-05 19:23 Artech      
@Cheney Shue
:)

 回复 引用   
#6楼 2007-07-05 20:25 ppmmw[未注册用户]
很受教益!
 回复 引用   
#7楼 2007-07-05 21:01 wcf[未注册用户]
请教一下博主,文中的图片是用什么软件做的?
 回复 引用 查看   
#8楼[楼主] 2007-07-05 21:07 Artech      
@wcf
PS画的。

 回复 引用 查看   
#9楼[楼主] 2007-07-05 21:10 Artech      
@ppmmw
谢谢!!

 回复 引用   
#10楼 2007-07-06 08:44 deerchao
发一篇好文章不难,难的是每一篇文章都好!
楼主真是个强人!

 回复 引用   
#11楼 2007-07-06 08:54 idior[未注册用户]
之前学习kerberos的时候也写过一些体会,不过是总结性质的。
http://www.cnblogs.com/idior/archive/2006/03/20/354027.html

另外检验Artech在发表文章的时候,能给出些参考资料。 :P

 回复 引用   
#12楼 2007-07-06 08:57 idior[未注册用户]
检验-->希望

kerberos最大的缺点就是缺少抗否认性,无法应用于电子商务和政务等等场合。

值得期待下一篇
 回复 引用   
#14楼 2007-07-06 10:09 Anders Liu
好文章!

Kerberos本身就是一个复杂的概念,博主能阐述到这个份上,已经很不容易了!

验证码:4186

 回复 引用 查看   
#15楼[楼主] 2007-07-06 10:34 Artech      
@deerchao
@idior
@学海无涯,回头是岸
@Anders Liu
谢谢各位,我会尽量把这篇文章写好。

 回复 引用 查看   
#16楼[楼主] 2007-07-06 10:36 Artech      
@idior
谢谢你的建议,列出参考确实很有必要。

 回复 引用   
#17楼 2007-07-06 12:35 U2USoft
好文章
 回复 引用 查看   
#18楼[楼主] 2007-07-06 13:24 Artech      
@U2USoft
:)

 回复 引用   
#19楼 2007-07-08 11:30 phj[未注册用户]
好文章,受益非浅!
 回复 引用 查看   
#20楼[楼主] 2007-07-08 11:34 Artech      
@phj
谢谢,别人觉得有价值是我的最大动力!

 回复 引用   
#21楼 2007-08-27 23:10 5lin[未注册用户]
记得Kerberos有三个头守卫着网络的大门,代表着认证、清算、和审计。只是现在只是完成的认证的功能。
 回复 引用   
#22楼 2007-09-12 17:34 过路人[未注册用户]
写的太好了,让人有豁然开朗的感觉,谢谢你的贡献。
 回复 引用 查看   
#23楼[楼主] 2007-09-12 17:46 Artech      
@过路人
谢谢你的关注!

 回复 引用 查看   
#24楼 2007-09-29 10:28 EagleFish      
请教楼主一个问题:

在“为什么要使用Timestamp?”这个小节中,楼主提到“Client向Server发送的数据包被某个恶意网络监听者截获,该监听者随后将数据包座位自己的Credential冒充该Client对Server进行访问,在这种情况下,依然可以很顺利地获得Server的成功认证”。我不明白的是,client向server发送的数据包分别是用session key和server端的master key加密过的,监听者怎么能替换成自己的credential呢?是不是说没有时间戳的话,监听者可以用很多时间来去破解密码,从而有把数据包破解开的危险?

 回复 引用 查看   
#25楼[楼主] 2007-09-30 20:26 Artech      
@EagleFish
Timestamp在整个Kerberos Authentication起着重要的作用,可以防止冒用截获的Token。
比如B截获A的Token,然后使用该Token以A的名义访问某个受限制的资源。如果没有Timestamp,认证方无法判断Token的发送方是不是A。现在有了Timestamp,在认证的时候,如果Timestamp早于或者等于A上一个通过认证的Timestamp,则会直接认为该Token无效,验证失败。

 回复 引用   
#26楼 2008-01-29 16:31 访客[未注册用户]
讲得很好,谢谢!
 回复 引用   
#27楼 2008-05-22 11:52 bullstraight[未注册用户]
请问博主几个问题:
1、Kerberos 所采用的改进模型User2User,既然不在Win2K中使用,那么会用Win2k3还是Win2k8里呢?
2、Kerberos 所采用的对称算法是哪一种呢?DES、RC4更或是TDES?或者其它更先进的?
3、是否在新版本里加入完整性与签名机制
期待。。。
谢谢!

 回复 引用 查看   
#28楼 2009-10-09 15:47 windalucard      
非常喜欢这篇文章写得也很通俗易懂并且又不失深度是篇好文章期待更多的佳作。另外有一处没理解望楼主解答。

Client向Server发送的数据包被某个恶意网络监听者截获,该监听者随后将数据包座位自己的Credential冒充该Client对Server进行访问,在这种情况下,依然可以很顺利地获得Server的成功认证。我认为该冒充的用户因为没有master key所以也无法获得Session Key。不知如何取得信任。

 回复 引用 查看   
#29楼 2010-02-28 15:46 darling      
贼好!!!
 回复 引用 查看   
#30楼 2010-02-28 16:35 darling      
对于Timestamp的作用不是很清楚,我理解是有了时间标志,可以判断是否是重复的数据包,因为它是唯一的。
 回复 引用 查看   
#31楼 2010-07-21 16:25 灰鸟      
楼主讲的很详细,看完后我有下面两个疑点:
1.恶意监听者如果截获了client发送给server的数据包后,怎么冒充自己的credential进行验证,监听者的client-info和数据包里的client-server应该是不一样的吧?
2.监听者如果能以截获的数据包进行验证的话,那么timestamp好像也起不到作用吧?监听者截获的数据如果比真正的client的数据先到达server端的话,那么真正的client不是要被拒绝了?

 回复 引用   
#32楼 2011-04-17 10:31 Guest111[未注册用户]
VERY GOOD!!!
 回复 引用 查看   
#33楼 2011-12-08 14:20 xingyanguang      
多谢能提供这么好的资料
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 807492 5UJNK66tMBM=