天王盖地虎,小鸡炖蘑菇-----浅析kerberos认证

引子

在战争时期,晚上宵禁,禁止随便出入城池,为了辩清敌我,会向将军或者一个专门的部门去请求编一套暗号。这时如果夜晚有一队想进入城池,守城的就会先来句天王盖地虎,进城的回复一个小鸡炖蘑菇,对上了就可以判定是友军,允许进城,如果他不知道或者对错了,那就不让进甚至要逮住问问到底是敌是友了(当然kerberos不会逮住你问你是敌是友)。简单来说就是用一个大家都知道的暗号(key)来进行验证,为了防止敌军截获到这个暗号装扮成友军发动突袭,这个暗号基本一晚一变,来确保安全性。通过上面的描述我们引入kerberos里面的几个概念:
Client:夜晚进城的那一队。客户端,也就是谁发起的访问
Server:被防守的城池。服务端,就是Clinet最终要访问的服务器
KDC:Kerberos Distribution Center ,这个角色比较重要,是kerberos的核心,简单粗暴的解释就是暗号的生产者,可能是驻扎军队的将军或者专门的部门,他受到client和server的信任,并把暗号发给所有登记在册的人。在kerberos里面Clinet要先访问KDC来获取一些凭证(那server呢,我们后面再说)。
以上三个角色是kerberos系统的主要组成,三者协作完成整个的认证过程。有关暗号还有以下两个概念:
long-term key:也叫master key,由这种key派生出来的也属于long-term key,长期不变。这里可以简单理解为一种长期不变的暗号,用来做经常呼喊的暗号不是很合适,因为在呼喊的过程中,一旦被敌军耳目听到,那敌军就会很容易的去伪装成友军混进城池发动突袭,无法保证安全。
short-term key:也叫session key,可以简单的理解为隔晚就换的暗号,短时间内有效,就算被敌军知晓,第二晚再用的时候就会因为过期被禁止入内或者进了牢房了。安全性得到了提高。
当然,上面的例子只是简单的引出了kerberos的几个基本概念和极简的认证形态,相对于真正的实现就太简单粗暴了,但是有助于理解,同时也不得不佩服老祖宗们的智慧,这些暗语既神秘又实用。

kerberos的认证的过程-土话版

按我们的理解,client想要访问某个server了,没有kerberos的认证(kerberos称为ticket)肯定是不行的,这时候client就得向KDC申请了ticket了,只有有了这个ticket,client才能去访问这个server。在这之前client首先需要向KDC申请TGT,啥意思?啥内容?如下:
1, client向KDC申请TGT(Ticket Grantting Ticket),TGT是什么?就是允许client获取ticket的凭证,TGT的生成过程如下,首先KDC为client生成一个专属于client和KDC通信的sessionkey,为了保证这个sessionkey仅供该client使用,就分别通过client的master key和KDC的master key对sessionkey进行对称加密,其中用masterkey加密的信息除了这个sessionkey里面还包含了client的一些信息(clientinfo),这就是TGT,然后把client的masterkey加密的sessionkey和TGT一块返回给client,注意KDC不会保存任何sessionkey和TGT。
2, client收到client的masterkey加密的sessionkey和TGT后,先用自己的master解密sessionkey,并缓存该sessionkey和TGT。
3, 注意既然是sessionkey就会有过期时间,一旦过期sessionkey和TGT均过期,需要重新申请,KDC会生成完全不一样的sessionkey和TGT给client。
以上就是获取TGT的过程,那么获取到TGT了,client就可以去申请ticket了。过程如下:
1, Client首先生成Authenticator(clientInfo和一个timestamp)连同要访问的server名一块用sessionkey进行加密,最终连同TGT一块发送给KDC
2, KDC通过自己的masterkey对TGT进行解密,获得TGT中的sessionkey和clientinfo,然后用sessionkey去对Authenticator进行解密获得clientinfo,比对clientinfo, clientinfo一致,准备生成ticket。
3, 首先KDC会重新生成一个sessionkey(不同于上面的sessionkey),用于client和server的通信,为了仅让该client和该client要访问的server使用,KDC又要加密啦!这次使用client和KDC的sessionkey和server的masterkey对新的sessionkey进行加密,依照惯例,后者的加密依旧添加了clientinfo(后者就是Ticket)。然后将前后两者一块返回给client。为啥不把sessionkey分别给client和server?原因有二:1是server要面对的client可能会非常多,他都要进行维护的话岂不是要累到吐血。2是有可能因为网络延时client拿到sessionkey,server还没拿到,去访问结果访问不了,这不就尴尬了么。
4, Client拿到ticket后,先解密获取到用于client和server之间的sessionkey,然后用sessionkey对clientinfo和timestamp进行加密生成Authencator,最终连同Ticket一块去访问server。
5, Server获取到client的请求,用自己的Masterkey去解密Ticket获取到clientinfo和sessionkey,然后用sessionkey去解密client的Authencator获取到clientInfo和timestamp,比对clientinfo,校验是否超时,如果clientinfo一致且未超时,允许访问,否则拒绝访问。
综上,Kerberos的认证大体为:
a、client向KDC申请TGT,
b、client向KDC申请ticket,
c、client拿着ticket请求server进行验证。

不过上面的描述和kerberos真正的验证过程还有些出入。这些出入基本上就是方言和普通话之间的区别。下面咱们用普通话来介绍一遍。

kerberos的认证的过程-普通话版

实际上这些过程是通过kerberos的三个sub-protocol进行的。
1, Authentication Service Exchange
2, Ticket Granting Service Exchange
3, Client/Server Exchange

下面这个图简单的展现了这三个sub-protocol的信息交换过程
在这里插入图片描述

1, Authentication Service Exchange

通过这个service,KDC(准确的说是KDC里面的Authentication Service,简称AS)实现
对client的认证并给client颁发TGT。
Client向AS发送Authentication Service Request(KRB_AS_REQ),为了确保KRB_AS_REQ只有自己和KDC知道,client用自己的masterkey对KRB_AS_REQ的主体部分进行加密,KDC通过domain的Account database获取该client的masterkey对KRB_AS_REQ进行解密。KRB_AS_REQ包括以下信息:
◎Pre- Authentication -data:包含了client的一些信息。说白了就是说明自己知道自己声称的account的Password,一般是client端masterkey加密的timestamp。
◎Client Name & realm:Domain name\client
◎Server Name:实际上是Ticket Granting Service的servername。注意不是client要访问的server name,申请TGT跟最终要访问的server无关。
AS在接收到KRB_AS_REQ后会从domain的account databse中获取到该client的masterkey并对Pre- Authentication-Data进行解密,如果解密得到一个正常的timestamp则验证通过。之后,AS会发送KRB_AS_REP给client,KRB_AS_REP包括被client masterkey加密的sessionkey和被KDC masterkey加密的TGT,TGT包含以下几部分
◎Sessionkey
◎clientname & realm:Domainname\client
◎end_time:过期时间
Client在接收到KRB_AS_REP的第一部分进行解密得到Sessionkey,缓存Sessionkey和TGT,然后就可以带着相关信息进入下一阶段TGS了

2, Ticket Granting Service Exchange

Clinet向KDC中的Ticket Granting Service发送Ticket Granting Service Request(KRB_TGS_REQ), KRB_TGS_REQ包含以下部分:
◎TGT
◎Authenticator
◎clientname & realm
◎servername & realm:这里是要访问的server
TGS在颁发ticket之前会经过之前描述的过程解密验证client,验证通过会发送KRB_TGS_REQ给client,KRB_TGS_REQ包括sessionkey和ticket(加密方式同之前描述,这里不再赘述),ticket包括以下部分
◎SessionKey
◎client name & realm
◎end time
Client在接收到KRB_TGS_REQ会用跟KDC之间的sessionkey解密获得和server之间的sessionkey。然后封装自己的Authenticator并用和server之间的sessionkey进行加密,最终连同ticket进入Client/Server Exchange。

3, Client/Server Exchange

Client发送KRB_AP_REQ给server,这里需要注意下,kerberos支持双向验证,KRB_AP_REQ里除了Authenticator和ticket之外还有一个是否需要双向验证的标记,验证过程上面已经说过不再赘述,验证成功允许访问需要访问的资源,这里描述下双向验证。
前面提到Authenticator里面会有一个timestamp,server会解密得到这个timestamp,然后用与client之间的sessionkey加密发送给client进行验证。

其实除了以上三个sub-protocol,在新的kerberos里面还加入了新的protocol,叫user2user sub-protocol。为什么要有这个呢?我们知道在整个的kerberos安全认证中,Ticket的加密是用server的masterkey进行的加密,违背了基本的原则就是尽量减少masterkey在网络中的传输,user2user sub-protocol就是解决这个问题的。
在这里插入图片描述
如上图,加入User2User subprotocol之后多了一步。我们分步介绍:
1, 正常获取client的TGT
2, client获取Server和KDC的TGT。server通过AS Exchange获取KDC和server之间的sessionkey和通过KDC masterkey加密后的TGT,并缓存在本地,等待client请求。
3, KDC拿着自己的TGT,Authenticator,server的TGT去申请ticket。KDC会首先校验client端信息,然后用KDC新生成client与server之间的sessionkey,并用KDC自己的masterkey解密server的TGT获取KDC和master之间的sessionkey,并用这个sessionkey去加密ticket(包含client与server之间的sessionkey,clientinfo,enddate等信息),连同用解密得到的KDC与client之间的sessionkey加密新生成的client与server之间的sessionkey返回给client
4, Client解密获取client和server的sessionkey,并封装Authencator,连同ticket
传给server端,server端通过和KDC的sessionkey解密ticket获取和client的sessionkey和clientinfo,并通过和client的sessionkey解密Authencator获得clientinfo进行验证。

最后

罗列下kerberos的优点:
1, 高效。获取ticket之后就不需要再和KDC交互。
2, 支持双向验证。
3, 对delegation的支持,就是类似于咱们通过咱们的程序模拟client来访问hive或其他的资源
4, 互操作性,支持很多系统的互操作。

其中引用了一些文章的内容,举得例子不知道合不合适,如果您有其他的看法,请留言讨论~欢迎批评指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值