实验目的
Kerberos的基本思想
Kerberos的应用范围
Kerberos验证流程的原理
利用wireshark以及所掌握的知识分析Kerberos数据包
实验工具
wireshark
实验环境
操作机:Windows XP
实验步骤
Kerberos的基本思想
采用对称秘钥体制对信息进行加密,能正确对信息进行解密的用户即为合法用户。用户在对应服务器进行访问之前,必须先从Kerberos服务器获取该应用服务其的许可证(ticket)。
Kerberos的实现原理
那么这个Kerberos是什么意思呢?相信看过希腊神话或者《圣斗士-冥王篇》的朋友应该都知道,在渡过了冥河之后,冥界的大门由一只巨大的三头猎犬所看守,保证冥界的大门只许进不许出,令冥界之门固若金汤。而这只猎犬的名字就是Kerberos,应用于我们所讲的网络认证中,表示这是安全的象征。
在实际的网络应用中,Kerberos的认证结果是双向的,也就是当帐号A访问资源B的时候,不但B要确保A并非冒充,而且A也要查明B的真实身份。而双向认证的方式并不止一种,最简单的方式就是互报接头暗号。但是这种方式的弊端有很多,最大的问题是管理起来不方便。比如在一个数百名员工共享几百台机器的环境中,当加入一名新员工时,就需要在几百台的机器上更新帐号信息。那么这对于网络管理员来说是无法容忍的。
为了解决这个问题,Kerberos引入了一个权威的第三方来专门负责身份的认证工作。这个第三方就称之为KDC(Key Distribute Center),他知道所有的账号和密码。这样一来,假如账号A想要访问资源B,那么利用KDC就可以验证双方的身份了。因此,A和B都不需要知道对方的密码,可以完全依赖于KDC。
①用户想要获取访问某一应用服务器的许可证时,先以明文方式向认证服务器AS发出请求,要求获得访问TGS的许可证。
②AS以证书(credential)作为响应,证书包括访问TGS的许可证和用户与TGS间的会话密钥。会话密钥以用户的密钥加密后传输。
③用户解密得到TGS的响应,然后利用TGS的许可证向TGS申请应用服务器的许可证,该申请包括TGS的许可证和一个带有时间戳的认证符(authenticator)。认证符以用户与TGS间的会话密钥加密。
④TGS从许可证中取出会话密钥、解密认证符,验证认证符中时间戳的有效性,从而确定用户的请求是否合法。TGS确认用户的合法性后,生成所要求的应用服务器的许可证,许可证中含有新产生的用户与应用服务器之间的会话密钥。TGS将应用服务器的许可证和会话密钥传回到用户。
⑤用户向应用服务器提交应用服务器的许可证和用户新产生的带时间戳的认证符(认证符以用户与应用服务器之间的会话密钥加密)。
⑥应用服务器从许可证中取出会话密钥、解密认证符,取出时间戳并检验有效性。然后向用户返回一个带时间戳的认证符,该认证符以用户与应用服务器之间的会话密钥进行加密。据此,用户可以验证应用服务器的合法性。
Kerberos的原理的整个验证流程可以分为三大步骤,结合实验分析如下所示:
第一步,账号A和KDC互相认证。
1、账号A利用哈希函数将密码转化成一把密钥,这里称它为Key-Client。
2、利用Key-Client将当前的时间戳加密(对称加密),生成一个字符串。表示为“{时间戳} Key-Client”。
3、将上一步生成的字符串“{时间戳} Key-Client”、账号A的信息以及一段随机字符串发给KDC。这样就组成了Kerberos的身份认证请求AS-REQ,可以使用下面的公式来表示:AS-REQ=“{时间戳} Key-Client”+“账号A的信息”+“随机字符串”。
如下图所示:
这里需要注意的是,当前捕获文件中的数据是处于加密状态的,这不利于我们的分析。不过只要知道密码,就可以生成解密文,我们可以在菜单栏中选择“Edit”->”Preferences”->”Protocols”->”KRB5”,之后勾选两个选项,并输入解密文件的名称,之后就可以看到解密后的内容了。解密文件的路径最好不要有中文,放在C盘根目录下即可。之后再次查看第一个数据包的内容:
上图中的KerberosString后面的内容就是账号A的信息,而nonce后面的内容就是随机字符串。
4、KDC收到AS-REQ之后,读取到A的信息,就可以调出A的密码,再使用同样的哈希函数将其转化为Key-Client。有了Key-Client就可以解开“{时间戳} Key-Client”了。如果能够成功解开,就说明这个请求是由账号A生成的,毕竟其它账号不可能有Key-Client进行加密。
Kerberos之所以使用时间戳进行加密,原因就在于如果黑客在网络上截获了字符串“{时间戳} Key-Client”,那么就有可能伪装成账户A来欺骗认证。这种方式就称为重放攻击。采用这种攻击方式需要一定的时间,所以KDC把解密得到的时间戳和当前的时间作对比,如果二者的差异过大,那么就可以认为遭受到了重放攻击。假如采用与时间无关的字符进行加密,那么是无法避开重放攻击的,因此这就要求域中的所有计算机要在时间上同步。
5、接下来,KDC需要向账号A证明自己的身份,刚才提到的随机字符串就需要用在这里。理论上KDC只要使用Key-Client加密随机字符串,再回复给账号A就可以证明自己的身份了。因为假的KDC是没有Key-Client的,那么账户A收到假的KDC的回复后,解不开那个随机字符串,就知道KDC是假的。
总结上面的流程,账号A和KDC都没有向对方发送密码,所以即便有一方是假的也不会导致信息的泄露。如果双方都是真的,则可以实现相互认证的过程。但是这个机制中的KDC是非常忙碌的,因为每次的认证都需要调出密码账号、进行哈希运算、实现解密操作……每个客户端一天可能会验证数十次,那么域中就需要配置大量的KDC才能够负担得起,因此改进流程就显得很有必要了。Kerberos在这里设计了一个比较巧妙的方法:
【solution:】
a.KDC生成两把一模一样的密钥Key-Client-KDC,用于以后账户A和KDC之间相互的认证,这样就省去了调出账号A的密码和哈希等的工作。按理说其中的一把Key-Client-KDC应当由账户A保管,另一把由KDC自己保管。但是KDC本来就很忙碌,额外再保管密钥会加重自身的负担,因此这个密钥就委托给账户A来保管,那么以后账户A需要KDC的时候,再把这个密钥还回来就可以了。但是这里面有一个问题,那就是如果有个假冒的账户A交回来一个假的密钥怎么办?为了避免这个问题,KDC把自己的密码哈希成Key-KDC,然后用它加密那把委托给账户A的密钥。Kerberos将这个密钥称为TGT(Ticket Granting Ticket),可以用以下公式表示:
TGT={账户A的相关信息,Key-Client-KDC} Key-KDC
有了这个委托保管的机制,那么KDC只需要记住自己的Key-KDC,就可以解开委托给所有账号的TGT,从而获得与该帐号之间的密钥。通过这个机制,KDC的工作负担就大大降低了。那么总结以上可以知道,KDC回复给账户A的AS-REP应当包括以下信息:
AS-REP=TGT,{ Key-Client-KDC,时间戳,随机字符串} Key-Client
那么相对应的,就是捕获文件中2号数据包的内容:
这其中的ticket就是TGT,下面的key表示的是Key-Client-KDC,Lr-time是时间戳,nonce是随机字符串,它与第一个数据包中的字符串是一致的。
b. 账户A收到AS-REP之后,利用Key-Client解密“{ Key-Client-KDC,时间戳,随机字符串} Key-Client”,通过解密得到的随机字符串和时间戳来确定KDC的真实性,然后把Key-Client-KDC和TGT保存起来备用。
第二步,账号A请KDC帮忙认证资源B。
1、现在应当把TGT交还给KDC,其次还有账户A的相关信息、当前时间戳以及要访问的资源B的信息。这个请求在Kerberos中被称为TGS-REQ,可以使用以下公式表示:
TGS-REQ=TGT,{账户A的相关信息,时间戳} Key-Client-KDC,“资源B的相关信息”
如下图所示:
图中的ticket是要交还给KDC的TGT,下面的KerberosString表示A的帐号信息,ctime是时间戳,最后的两个KerberosString表示资源B的信息。
2、KDC收到TGS-REQ之后,先使用Key-KDC解密TGT得到Key-Client-KDC,再使用Key-Client-KDC解密出账号A的相关信息和时间戳来验证其身份。一旦认定账号A为真,那么接下来就要帮助A和B进行相互认证了。
3、KDC生成两把同样的密钥供A和B之间使用,我们就称这个密钥为Key-Client-Server。其中一把密钥直接交给账号A,另一把委托A转交给资源B。为了确保A不会受到假的资源B所骗,Kerberos把B的密码哈希成Key-Server,然后用它加密那把委托A转交给B的Key-Client-Server,成为一个只有真正的B才能够解密的ticket。总结以上,KDC给账号A的回复可以表示为:
Ticket={账号A的信息,Key-Client-Server} Key-Server
TGS-REP={ Key-Client-Server} Key-Client-KDC,ticket
这里的“账号A的信息”不单单包括A的名称,还包括A所在的域组(Domain Groups)。因此如果A属于很多个组(Groups),那么TGS-REP数据包就会很大。如下图所示:
上图中的ticket就是“{账号A的信息,Key-Client-Server} Key-Server”,cipher后面的内容就是“{ Key-Client-Server} Key-Client-KDC”,下面的keyvalue的值就是Key-Client-Server。
4、账号A收到TGS-REP之后,首先使用Key-Client-KDC解开{ Key-Client-Server} Key-Client-KDC,从而得到Key-Client-Server。Ticket留下来发给资源B。接下来如果需要多次访问资源B,都可以使用同一个ticket,而不需要每次都向KDC申请,这就降低了KDC的负担。
第三步,账号A和资源B互相认证。
1、这时候,账号A给资源B发送“{账号A的信息,时间戳} Key-Client-Server”以及之前收到的ticket,这个请求称为AP-REQ:
AP-REQ=“{账号A的信息,时间戳} Key-Client-Server”,ticket
如下图所示:
2、如果资源B是假的,那么它就解不开ticket。如果资源B是真的,它可以用自己的密码生成Key-Server来解开ticket,从而得到Key-Client-Server。有了Key-Client-Server就可以解开“{账号A的信息,时间戳} Key-Client-Server”部分。这样资源B就可以确定账号A为真,然后回复AP-REP来证明自己也是真的:
AP-REP={时间戳} Key-Client-Server
3、账号A利用Key-Client-Server来解密AP-REP,再通过得到的时间戳来判断对方是否为真。如下图所示:
实验结果分析与总结
Kerberos的主要优点:
通过对实体和服务的统一管理实现单一注册,也就是说用户通过在网络中的一个地方的一次登录就可以使用网络上他可以获得的所有资源。
Kerberos存在的问题:
①Kerberos服务器的损坏将使得整个安全系统无法工作;
②AS在传输用户与TGS间的会话密钥时是以用户密钥加密的,而用户密钥是由用户口令生成的,因此可能受到口令猜测的攻击;
③Kerberos使用了时间戳,因此存在时间同步问题;
④要将Kerberos用于某一应用系统,则该系统的客户端和服务器端软件都要作一定的修改。