Kerberos认证原理

参考博文 官方文档 参考博文2

前言

本文是在参考了两篇博文和官方文档基础上写成的,更多的是想通过自己学完复述一遍的方式加深理解。

Kerberos在希腊神话中是守护地狱之门的三头犬。在使用Kerberos中涉及到KDC(有些资料可能会叫做AS,即认证服务器)、客户端、服务器三方的身份认证问题,因此用Kerberos来进行命名还是十分贴切的。

概念学习

在开始正式的Kerberos学习之前,我们需要明白下面几个概念:

  • Long-term Key/Master Key:在安全认证领域中,有些Key(密码、秘钥)可以长期保持不变,比如你的QQ密码。这样的Key,以及由此派生的Key都被称为Long-term Key 。对于这样的Key在使用的时候有这样的原则:被加密的数据不能在网络中传输。原因很简单,只要有足够长的时间,任何密码都有可能被破译。

    对于一个账户而言,密码应该仅仅被自己知道,甚至对于这个Domain中的管理员都应该是保密的。但是这个密码又是验证自身身份的信息。在这种情况下,一般的做法就是对密码进行Hash处理。一般把Hash后的密码叫做Master Key。Hash算法是不可逆的,这样既保证了密码的保密性同时又保证了Master Key和密码在证明身份的时候具有相同的效力。

  • Short-term Key/Session Key:由于被Long-term Key加密的数据包不能用于网络传送,所以我们使用另一种Short-term Key来加密需要进行网络传输的数据。由于这种Key只在一段时间内有效,即使被加密的数据包被黑客截获,等他把Key计算出来的时候,这个Key早就已经过期了。

另外下面为了阐述方便,小C和客户端混用,小S和服务器混用。

需求

既然说使用Kerberos是为了进行安全认证。那么这里有必要重新阐述一下我们的需求。

如,Kafka消费者客户端(C)需要从服务器(S)中消费数据。为了安全的考虑,服务器需要Kafka消费者证明它就是它。这就出现了一个经典问题,如何证明我是我。如果是现实世界,你尚可以吐槽:我一个大活人在这站着了,还要证明什么?你能说出这句话是你出于对对方的信任。你觉得对方可以通过体貌特征,声线甚至是气味辨别你确实是你。但是计算机不可以。而且就算对方真的知道你就是你,但是由于制度的原因,大部分情况下你仍然需要提供一份你就是你的证明。比如去*局开一张身份证,然后拿着身份证再回来说,看到了吧。我和身份证上的人一模一样,我就是我!

通过上面的例子我们可以看出,在复杂的网络环境中,要想证明自己就是自己,必须找一到双方都信任的第三方机构进行公证,证明我就是我的问题。而这个第三方就有Kerberos提供。

简化版Kerberos认证过程

为了方便理解。我们把Kerberos认证过程做一下简化。

通过上面的需求分析,我们可以看到。客户端是需要一个第三方来进行辅助证明。而这个第三方在Kerberos中叫做KDC(Kerberos Distribution Center),即秘钥分发中心,它维护着客户端与服务器的Master Key,并提供“公证服务”。

漏洞版

为了进一步简化,这里先提出一个有漏洞的版本,帮助理解。

  1. 首先,客户端(C)会请求KDC,说我需要向服务器(S)请求资源,请您给我们做一下公证。
  2. KDC会查询自己的数据库,发现确实有一个名为C的客户端,也确实存在一个名为S的服务器。KDC说,那好,我给你们一对相同的秘钥(Session Key)。你的那份秘钥用你的Master Key进行加密。服务器的那份用他的秘钥加密,他的除了Session Key还有你的基本信息(Client Info)。你的那份解密拿到Session Key,对你的数据进行加密发给服务器。我会帮你解释你就是你的。
  3. 客户端(C)很高兴,拿到加密过的秘钥以后用自己的Master Key进行解密,得到Session Key。然后将自己的信息(Client Info)加密发送给了服务器(S)。
  4. 服务器那边听Kerberos说一会有个小C要来跟我取数据。没想到这么快就真的来了。然年后他先用自己的Master Key对KDC发送的秘钥包进行解密,得到了Session Key和Cilent Info。然后用这个Session Key去解密小C发来的数据,还真的解开了发现了Client Info,经过对比这两份Client Info完全一致。于是小S相信了小C的说辞,小C通过此种方式向小S证明了小C就是小C。

修复版

梦想总是美好的,但是天灾人祸不断的在发生,现实要比上面骨感的多。上面有两个很大的漏洞:

  • 由于网络等原因。如果KDC发送给小C的Session Key已经到了,但是服务器这边的Session Key迟迟没到势必会导致客户端向服务端发起认证的时候,服务端说我没有收到KDC的证明信息(Session Key和Client Info的加密包)啊。而且如果服务器为每一个客户端维护一份Session Key势必会造成服务器的压力。
  • 另外,在上面第三步客户端发送验证信息的时候,如果被M截获,并声称这是我M和你S的Session Key和Client Info,S是不是就被轻易的骗过了呢?

为了解决上面的两个问题提出了下面的修复版本

  1. 第一个步骤保持不变。
  2. 考虑到漏洞版中的漏洞。KDC说,小C啊,小S那边压力挺大的,为了分担他的压力,也为了避免网络问题,造成你们之间无法认证,我现在把两份Session Key都给你,然后你在向小S发起认证的时候把他的这一份加密包也一起发给他就好了。
  3. 小C欣然答应了KDC的话。并用自己的Master Key解密了KDC的数据包,得到了Session Key。同时小C为了防止数据包被小M截获,这次长了一个心眼儿,给自己生成了一个Authenticator,其中包含Client Info和Timestamp。客户端将这个Authenticator使用刚获得的Session Key 进行加密,与KDC给小S的加密包一起发送给了小S。
  4. 小S不是第一次跟KDC打交道了,一看这种情况就是KDC又做公证人了。于是轻车熟路的用自己的Master Key解密了KDC给自己的数据包。获得了Session Key和Client Info。并用Session Key解密了小C加密的Authenticator,但是小S却没有着急比较两个Client Info是否一致。他先比较了其中的Timestamp与自己的当前时间,如果这个时间相差超出一个可接受范围(一般是五分钟)。小S会直接决绝小C的请求。但是好在并没有超过五分钟。一丝不苟的小S查看了最近一次与小C通信的记录。只有当当前的这个时间戳晚于最近的一次小C认证通过的时间的时候,小S才会对两个Client Info进行比较。

Kerberos认证原理

上面的过程基本符合了Kerberos的认证原理,但是距离真正的认证过程还是差一点。

完整版Kerberos认证过程

为什么上面的流程还是不是Kerberos的完整过程呢?很明显,其中还是存在一个比较严重的漏洞。我们在概念学习章节中已经提到了,Long-term Key是不能够用于网络传输的,因为只要时间足够长,就可能会被破译。但是上面在介绍认证过程的时候还是打脸的使用了使用了客户端的Master Key进行加密。为了解决这个问题,Kerberos又引入了TGS(Ticket Granting Service)的概念。TGS和KDC都是Kerberos的一部分,位于同一台服务器上。

完整的认证过程由上面的四步,扩充到了安全的六步。

  1. 小C向KDC请求做与小S的公证。
  2. 但是这次KDC说,我跟你通信只能用你的Master Key加密,这样不安全。这样吧,你去联系TGS,有问题你跟他讲就好了。至于你怎么跟他联系我会给你一个你跟他联系的Session Key。同时我会把这份Session Key连同你的身份信息用他的Master Key进行加密,到时候你一并发给他他就明白了。
  3. 于是小C用自己的Master Key解密了属于自己的数据包,同时为了安全起见,小C创建了Authenticator(Timestamp+Client Info)用Session Key 加密同KDC给TGS的那一份加密包一起发给了TGS。(类似修复版中的步骤3)
  4. TGS也是轻车熟路的用自己的Master Key(TGS和KDS是同一个“人”,master key也是一样的)解密了数据包,获得了Session Key。然后用Session Key解密了小C的数据包,然后一顿验证操作(与修复版第四个步骤一致)证明了C确实是C。于是找出了小S的密码,用小S的密码加密了TGS为小S和小C生成的Session Key。同时小C也有一份。并把两份都发给了小C,告诉它你用我(TGS)和你(小C)的session Key解密这份Session Key(小C和小S的),然后用它加密你的信息发给小S,他会懂的(这与步骤2几乎相同,不同的是加密小C和小S Session Key用的不再是小C的MasterKey,而是TGS和小C之间的Session Key)
  5. 然后小C轻车熟路的用C-TGS Session Key解开了加密包得到了C-S Session Key。然后对Authenticator(Client info +Timestamp)使用C-S Session Key进行加密。发送给了小S
  6. 小S得到这两份数据包以后先用自己的Master Key(小S的Master Key一直没有在网络上使用,仅仅在这里做了本地验证)进行了界面,得到与小C的Session Key和Authenticator。然后又是一顿验证操作。最后证实小C确实是小C。

Kerberos认证原理

小C露出了欣慰的笑容。

总结

上面验证过程中出现了两对Session Key 是不一样的。TGS和小C间的Session Key有效时间相对比较长。小C在第一次验证结束以后在一定时间内就不需要再进行步骤1/2了,而是直接从3开始。

小C仅需要使用与TGS的Session Key获取与小S的Session Key 就好了。所以完整版的整个过程在一个周期内基本还是只需要四步,但是与简化版不同的是,获取与小S通信的Session Key的时候使用的是Short-term Key来获取的,而不是简化版中的小C的Master Key。这样进一步提高了安全性。

完整版中的前两步完成了生成ticket操作。这个ticket的生命周期由两个参数控制ticket_lifetime/renew_lifetime。分别表示票据(ticket)的有效时间,默认1天,和允许更新现有ticket的时长,默认七天。即当前票据可以允许七天以后才重新生成。