票据就是token就是令牌,这里token是由kerberos工具签发的,kerberos充当 这个有效token 的权威签发处,kerberos将其签发的客户端身份证token给应用服务器端,告知应用服务器这个客户端 token值是kerberos签发过的是被认证过的,kerberos会同时给通信双方一个会话秘钥在通信双方之间(客户端和应用服务器之间共享),只有这个会话秘钥有效,且通信双方互相能对上,这样的客户端和应用服务器之间才能通信
在希腊神话中Kerberos是守护地狱之门的一条凶猛的三头神犬,Kerberos认证协议是由美国麻省理工学院(MIT)首先提出并实现的
这个定名是贴切的,因为Kerberos认证是一个三路处理过程,依赖称为密钥分发中心(KDC:key distribute center)的第三方服务来验证计算机相互的身份,并建立密钥以保证计算机间安全连接。本质上每台计算机分享KDC分发的一个秘钥,而KDC有两个部件:一个Kerberos 认证服务器和一个票据及token授权服务器 ,如果KDC不知道被请求目标服务器,则会求助于另一个KDC来完成认证,多个KDC可以级联互联相互路由到,能够转发请求,它允许在网络上通讯的双方互相证明彼此的身份,并且能够阻止窃听和重放等攻击手段。不仅如此,它还能够提供对通讯数据保密性和完整性的保护。
主体的标识不能频繁地循环使用,通信参与者的身份认证信息不能总是使用一个应该定期换一换这样安全性更高。由于访问控制的典型模式是使用访问控制列表(ACLs)来对主体进行授权。如果一个旧的ACL还保存着已被删除主体的入口,那么攻击者可以重新使用这些被删除的用户标识,就会获得旧ACL中所说明的访问权限。
在网络中,认证主要用来解决各个通讯实体之间相互证明彼此身份的问题。对于如何进行认证,我们通常会采用这样的方法:如果一个秘密仅仅由认证方和被认证方知道,认证方可以通过让被认证方提供这个就他两知道的秘密来证明对方的身份。这个过程实际上涉及到认证的三个重要方面:秘密如何表示、被认证方如何向认证方提供秘密、认证方如何识别秘密。
本文中的KServer-Client就是通讯双方共享的秘钥
整个过程看起来非常简单,但是实际上Kerberos认证远比这个过程复杂的多,在了解Kerberos真实的认证过程之前我们先给出两个重要的概念:
长期密钥:在安全领域中,有的密钥可能长期内保持不变,比如密码,可能几年都不曾改变。这样的密钥以及由此派生的其他密钥被称为长期密钥。长期密钥有这样的原则:被长期密钥加密的数据不应该在网络上传输。因为任何加密算法都不可能做到绝对保密,一旦这些被长期密钥加密的数据包被黑客截获,在理论上,只要有充足的时间,都是可以通过计算获得用户用于加密的密钥的。
对于一个账户来说,密码仅限于该账户的所有者知晓,甚至对于管理员都应该是保密的。但是密码却又是证明身份的凭据,所以必须通过基于密码的派生信息来证明用户的真实身份,在这种情况下,一般将账户密码进行Hash运算得到一个Hash值,也可以称之为主密钥。由于Hash算法是不可逆的,同时可以保证密码和主密钥派生的确定性,这样既保证了密码的保密性,同时又保证主密钥和密码本身在证明用户身份时具有相同的效力。
短期密钥:由于被长期密钥加密的数据包不能在网络上传送,所以需要使用另一种密钥来加密需要进行网络传输的数据。这种密钥只在一段时间内有效,即使加密过的数据包被黑客截获,等他把密钥计算出来的时候,这个密钥早就已经过期了。我们把这种密钥称为短期密钥。
以上这句话的意思是:客户端首先向KDC请求会话秘钥(session-server-client-key本文简称:sserver-client),会话秘钥sserver-client,用于客户端和服务器在会话期间进行对称秘钥数据加密,KDC接受到客户端的秘钥请求后首先会生成一个会话秘钥sserver-client,为了保证这个密钥仅限于发送请求的Client和他希望访问的Server知晓,KDC会为这个会话密钥sserver-client生成两个拷贝副本,然后分别被Client和Server使用。然后KDC从KDC处数据库中提取Client和Server的各自的先前存放的主密钥分别对这两个拷贝进行对称加密。对于要给服务器端的会话密钥一起被加密的还有一些关于Client的信息。
KDC有了两个分别被Client的主密钥和Server 的主密钥分别加密过的会话密钥,KDC会将这两个被加密的会话秘钥拷贝副本一并发给Client,属于Server的那一份将会由Client发送给Server。这样做可以轻松地解决两个问题:首先Server不用维护一张庞大的会话密钥列表来应付不同的Client的访问,降低了Server的负荷;其次避免出现因为网络延时,Client的认证请求到达server端时候,比Server接受到的会话密钥提前,(Server端如果没有 sserver-client-key这个会话秘钥的话是无法对客户端client进行身份认证的)早到达Server端,进而导致Server端认证客户端身份失败的情况(因为 Server端没有会话秘钥的话无法对客户端进行身份认证,如果客户对服务器的请求提前到来此时服务器端还没有SServer-client-key这个会话秘钥的话,服务器端对客户端进行身份认证就会失败)(Server端是通过client端有与其持有一样的会话秘钥来对客户身份进行确认和认证的)
在上述的过程之后Client实际上获得了两组信息:一个是通过自己的主密钥加密的会话密钥,另一个则是被Server的主密钥加密的数据包,其中包含会话密钥和关于客户端自己的一些身份确认信息。虽然通过一个双方知晓的会话密钥就可以对对方进行有效的身份确认认证,但是在一个不安全的网络环境中,这种简单的做法是存在安全漏洞的,假设Client向Server发送的数据包被黑客截获,该黑客随后将数据包(内部有SServer-client-key会话秘钥)作为自己的凭证冒充该Client对Server进行访问,在这种情况下,依然可以很顺利地获得Server对client身份的成功认证。为此,Client需要提供更多的附加身份证明信息,称为鉴别码 /验证码。在Kerberos中这个鉴别码实际上就是关于Client的一些信息和当前时间的一个时间戳。
Client使用自己的主密钥对KDC用该主密钥对称加密的会话密钥进行解密从而获得SServer-Client这个会话秘钥,随后创建鉴别码(鉴别码=指的是客户端身份资料信息+时间戳)并用SServer-Client会话秘钥对其(指的是客户端身份资料信息+时间戳)加密。最后连同从KDC处获得的、被Server的主密钥加密过的数据包(这个数据包内容是Sserver-client-key会话秘钥+客户端身份资料信息)一并发送到Server端。我们把通过Server的主密钥加密过的数据包称为会话票据即Session-token,( Session-token=Sserver-client会话秘钥+ 客户端身份资料信息)
当Server接收到这两组数据后,先使用他自己(Server端)的主密钥对会话票据(Session-token=Sserver-client-key会话秘钥+客户端身份资料信息)进行解密,从而获得SServer-Client-key(会话秘钥)。随后使用SServer-Client-key解密鉴别码(鉴别码=客户端身份资料信息+时间戳)获取时间戳,同当前的时间进行比较,如果偏差超出一个可以接受范围,Server会直接拒绝该Client的请求。Server会维护一个列表,记录在可接受的时间范围内所有进行认证的Client和认证时间。对于时间偏差在可接受的范围中的Client,Server会从列表中获得该Client最近一次认证时间,只有当Client提供的时间戳晚于这个时间,Server才会比较鉴别码(鉴别码=客户端身份资料信息+时间戳)中的客户端信息(客户端身份资料信息)和会话票据(Session-token=Sserver-client会话秘钥+ 客户端身份资料信息)中的客户端信息即(客户端身份资料信息)的比较,比较结果一致从而实现对Client的身份资料信息的认证(客户端的身份认证)。这也就是为什么我们从一开始就需要假定网络中每台主机的时钟必须是松散同步的了。
Kerberos一个重要的优势在于它能够提供双向认证:不但Server可以对Client进行认证,Client也能对Server进行认证。如果Client需要对他访问的Server进行身份认证,会在他向Server发送的认证请求中设置一个是否需要双向认证的标志位。Server在对Client认证成功之后,Server会把client 发给Server的鉴别码中的时间戳提取出来,通过SServer-Client会话秘钥进行加密,当Client使用SServer-Client会话对Server回应的报文进行解密之后,如果确认时间戳和原来的完全一致,那么Client客户端可以认定这台Server正是他希望访问的Server 。(注意以上提到的加解密过程都是对称秘钥加解密算法的实现),会话秘钥是对称加/解密算法使用的秘钥,这里另一种秘钥:主密钥这里也是用在了对称秘钥加/解密算法当中的秘钥
Kerberos实际上是一个基于Token的认证方式。 Client想要获取Server端的资源,先得通过Server的认证;而认证的先决条件是Client向Server提供从KDC获得的一个由 Server的主密钥加密过的会话票据即
session-token=利用Server主密钥加密函数(Sserver-client-key会话秘钥+客户端身份资料信息)。所以对Client来说,获得会话票据session-token是整个认证过程中最为关键的部分
在 Kerberos中票据的分发过程远没有上面所讲的那么简单,Client在从KDC处获得Server-client-Session-token会话票据之前,需要先获得一个授权,被称为Ticket Granting Ticket(票据授权票据,简称TGT),TGT的分发仍然是KDC来完成的。
首先Client向KDC发起对TGT的申请,KDC在收到该申请后,生成一个用于该Client与KDC进行安全通信的会话密钥KDC-client-Session-key,暂时用Session-KDC-Client-key来表示。为了保证该会话密钥Session-KDC-Client-key仅供该Client和自己(KDC自己)使用,KDC使用Client的主密钥和KDC自己的主密钥对已经生成的会话密钥进行加密,从而获得两个加密的Session-KDC-Client-key即(session之意)SKDC-Client的拷贝。对于后者,随会话密钥一起被加密的还包含以后用于鉴定Client身份的关于Client的一些身份特征信息,这就是前面所说的TGT(Ticket Granting Ticket)。最后KDC将这两份拷贝一并发送给Client。
通过以上的介绍,Kerberos认证的过程已经基本介绍清楚了,首先Client向KDC申请TGT(授权票据),之后Client通过获得TGT向KDC申请用于访问Server的会话票据会话Token(session-kdc-client-key),最后Client向Server提交票据(身份认证tocken)用于作为身份认证的凭据。
上一节所讲述的Kerberos认证过程的三步是通过三个子协议来完成,它们分别是:Authentication Service Exchange、Ticket GrantingService Exchange和Client/Server Exchange。这三个子协议分别完成了Client向KDC申请TGT、Client通过获得的TGT向KDC申请用于访问Server的票据(会话token+自己的身份认证信息(clinet_info))和Client向Server提交票据(sessionToken+client身份info)进行身份认证的三个过程。
图7 Kerberos三步认证过程
首先Client向KDC的认证服务发送Authentication Service Request(KRB_AS_REQ),大体内容包含:客户端名称、票据(Token分发服务器)授权服务器名称以及一个被Client的主密钥加密的时间戳TimeStamp,我们可以把它看作是票据(token)的有效期
认证服务从数据库中提取KRB_AS_REQ中携带的客户端名称的客户端标识所对应关联的客户端主密钥对被加密的时间戳进行解密,如果这个时间戳合法,则可以证明发送方(客户端)提供的是正确的密钥以加密了该时间戳, 认证服务将一份包含使用Client的主密钥加密的会话密钥和被自己的主密钥加密的TGT的回应(KRB_AS_REP)发送给Client(注意client处始终有它自己的主密钥,而kdc 处的数据库中也存放了client的主密钥)。这个TGT中包含了Session-KDC-Client-key指的是会话秘钥+客户端名称信息和 客户端相关信息和TGT到期的时间。
Client对第一部分解密获得Session-KDC-Client-key之后,携带着TGT即token grant token便可以进入下一步——TGS(Ticket Granting Service)Exchange服务进行交互。
Client向KDC的票据授权服务发送Ticket Granting Service Request(KRB_TGS_REQ),内容包括Client通过AS Exchange获得的TGT、使用Session-KDC-Client-key加密的客户端信息(client-info)以及所需要访问的服务器名称。
票据授权服务收到请求后,先得确认Client提供的那个TGT是否是AS颁发给它的。方法很简单,KDC先使KDC用自己的主密钥对Client提供的TGT进行解密,获得Session-KDC-Client-key它是KDC服务器和client之间的会话秘钥,会话期秘钥,再使用Session-KDC-Client-key解密鉴别码进行验证。验证通过KDC会向client发送Ticket Granting Service Response(KRB_TGS_REP)。回应报文也由两部分组成:使用Session-KDC-Client-key这个秘钥加密的Client和Server的会话密钥(SServer-Client指Session-server-client-key应用服务器和客户端在会话期间使用的会话秘钥)和使用Server的主密钥加密的token,包含SServer-Client即session-server-client-key,客户端名称和token的到期时间。(注意加密秘钥都是可用来加密数据用的作料因素,
密文=加密函数(加密秘钥,待加密的明文))
Client收到回应报文后,使用Session-KDC-Client-key解密第一部分,获得Session-Server-Client-key。有了Session-Server-Client-key和token,Client就可以直接和Server进行交互,而无需再通过KDC了。
最后Client使用token和Server进行交互就由CS(Client/Server)Exchange来完成。Client通过TGS Exchange获得SessionServer-Client-key,随后创建用于证明自己就是 token真正所有者的鉴别码,并使用SessionServer-Client-key进行加密。最后将这个被加密过的鉴别码和token作为应用服务请求(KRB_AP_REQ)发送给Server,另外在请求中还包含一个标志位用于表示Client是否需要进行双向验证。
Server接收到请求之后,通过Server自己的主密钥解密token,从而获得SessionServer-Client-key。接着使用SessionServer-Client-key解密鉴别码,进而验证Client的身份。如果验证通过,则让Client访问需要访问的资源,否则直接拒绝对方的请求。
如果Client需要进行双向验证,Server从鉴别码中提取时间戳,使用SessionServer-Client即 session-server-client-key进行加密,并将其发送给Client用于Client验证Server的身份。 明文=解密函数(解密秘钥,已经加密的密文信息)
通过对上述三个子协议的介绍,我们已经了解了整个Kerberos的认证过程。但是细心的读者也许会发现,基于这三个子协议的Kerberos系统是存在一定的安全隐患的。在CS Exchange阶段,Client携带的token是被Server的主密钥加密的,这显现不符合前面提出长期密钥的使用原则,降低了Server的安全系数。
最直接的解决方式就是采用一个会话密钥,而不是用Server的主密钥对token进行加密。这就是Kerberos的第四个子协议:User-to-User Authentication Exchanges。token是由KDC生成之后通过Client发送给Server的,所以用于加密token的自然是KDC和Server之间的会话密钥(SKDC-Server)。但是KDC是不会维护任何会话密钥的,所以Session-KDC-Server-key只能靠申请 token的Client提供给server??。
-----------------------------------------------------------------------------------------------
首先通过AS Exchange,Client获得了属于自己的TGT,便可凭此向KDC申请用于访问某个Server的token。
第二步的主要任务是获得封装了SKDC-Server即Session-kdc-server-key的属于Server的TGT 即ticket -grant-ticket。如果该TGT存在于Server的缓存中,则Server会直接将其返回给Client。否则Server将通过AS Exchange从KDC获取。
接着Client通过向KDC提供自己的TGT(即ticket-grant-ticket),Server的TGT以及鉴别码来申请用于访问Server的票据即 token。KDC先用自己的主密钥解密Client的TGT获得SKDC-Client,通过SKDC-Client解密鉴别码验证发送者的身份,验证通过后再用自己的主密钥解密Server的TGT获得SKDC-Server即Session-kdc-server-key,并用SKDC-Server即Session-kdc-server-key加密 token返回给Client。
最后,Client将使用SKDC-Server加密的票据token和SServer-Client即session-server-client-key加密的鉴别码访问Server,Server通过SKDC-Server解密票据获得SServer-Client,通过SServer-Client解密鉴别码实现对Client的身份验证。
在分析了整个Kerberos认证过程之后,Kerberos的优点也体现出来了。首先它具有较高的性能,一旦Client获得用于访问某个Server的票据即token,则该Server就能根据票据(token)实现对Client的验证,不再需要KDC的参与;其次Kerberos可以进行双向验证,Client在访问Server的资源之前可以要求对Server的身份进行验证;第三就是互操作性,Kerberos最初由MIT提出并实现的,现在已经成为计算机领域一个被广泛接受的标准,所以使用Kerberos可以轻松实现不同平台之间的互操作。
但是Kerberos的缺点同样存在,比如Kerberos身份认证采用的是对称加密机制,加密和解密使用相同的密钥,安全性有所降低;Kerberos中身份认证服务和票据授权服务时集中式管理的,容易形成瓶颈,系统的性能和安全性也过分依赖于这两个服务的性能和安全