基本概念

基于session key的认证

密码学中的身份验证基于一个事实

该实体能够通过知道一个秘密来证明自己的身份

但是在一个开放的网络环境中,直接公布自己所知道的这个密码是非常不安全的,Kerberos认证的优越之处就在于它可以避免上面这种情况的发生,并对实体的身份进行验证。

我们可以姑且称之为秘密地进行身份认证

为了达到上述目的,认证过程中的两个实体需要共享一个秘密进行*,而且这个session key也是秘密的,就只有他俩知道。注意这个session key采用对称加密方式,即使用同一个密钥进行加密和解密。

由于双方都拥有只有他们才知道的session key,他们就可以通过加密通信来验证对方的身份了(能解密对方的加密信息即证明对方就是其所声称的实体

下面就讲一下基于session key的身份认证:

客户端使用session key加密一段信息,这个被称作authenticator,然后把它发送给服务器,每次发送的authenticator都是不一样的,否则可能会被其他的恶意client重复使用(即使该client)并没有session key

服务器收到authenticator后使用session key进行解密,如果解密后的信息是有逻辑的、可读的,则服务端就会认为客户端就是它所声称的那个客户端

下面就轮到服务器来自证身份了,服务器将解密后的authenticator中的原始信息(客户端加密前的message)提取出来,并使用session key重新加密,发回给client,client收到之后,使用session key对该数据包进行解密,并和之前的message进行对比,如果两者一致,则说明服务器就是自己所认为的哪个服务器,自此认证结束。

从上面可以看出来,这种认证方式的思想就是:
我们两个拥有同一个秘密,为了证实对方的身份,并保证这个秘密不会被泄露,我们使用这个秘密去生成另外一个秘密,这个新生成的秘密只有拥有初始秘密的人才能看懂,如果你能看懂,那么你就证明了自己的身份

大致过程如下:
Windows Kerberos 协议_经验分享

session key的分发

我们上面说了那么多,但是却没有说session key到底是怎么被分发到clientserver手上的

在实际工作环境中,一个client需要拥有很多server的session key,一个server也要拥有很多clientsession key,这样一来key的分发就成了问题,而且在主机上保存这么多session key是一个很大的风险。

Kerberos协议就像希腊神话中的拥有三只头的地狱犬一样,也拥有三只头,一个是client,一个是server,一个是KDC,这个KDC就是受信任的第三方。

可以把KDC看作是运行在一个物理安全的服务器上的服务,它维护一个数据库,该数据库中保存着其领域内所有安全实体的账户信息。这里的领域等同于windows中的domain概念

KDC会和安全实体共享一个master key,在大多数对Kerberos Protocol的实现中,master都是安全实体密码的hash

当一个client想与server建立安全连接时,client会先向KDC发送一个请求包,然后KDC会创建出用于clientserver进行身份认证的唯一的session key。因为KDC拥有clientservermaster key的访问权限,所以它可以分别使用cleintservermaster key来对该session key进行加密。

KDC可以简单地通过将加密后的两个session key分别发送给clientserver来完成自己的任务,但是在实际过程中并不是这样的KDC会将两个经过加密的session key全部发回给clientserversession key被嵌入到数据包中一个被称作ticket的字段中,这个其实就是session ticket,在clientserver发起连接请求之前,client有责任将session ticket保存好。

KDC只提供票据授予服务(ticket-granting service),client和server有责任保护好各自的master key

session tickets

client收到KDC的响应包之后,提取出session ticket和属于自己的加密后的session key,并将它们放到安全的缓存中。为了和server建立一个安全的连接,client需要将session ticketauthenticator(这个在上面的基于session key的身份验证中已经提到过)一并发送给serversession ticketauthenticator共同组成了client凭证

server收到来自client的数据包之后,使用自己的master key解密session ticket,获取到session key,然后使用session key解密authenticator获取到authentication message,如果authentication message正常(可读),则client身份认证成功,然后serverauthentication message中的timestamp使用session key进行加密并发回给clientclient解密并和**初始authentication message**中的timestamp进行对比,一致则server身份验证成功。

client保存session ticket的好处就是可以减少server的工作,因为**server没有必要一直保存session key**,它只需要从client发来的认证数据包中的session ticket中解密出session key即可,当server不在需要session key时,直接将其删除即可。

session ticket失效之前client可以重复使用该票据来向server进行资源或者服务的访问,票据的有效时间取决于Kerberos policy。通常情况下不会超过8小时,相当于一个logon session的有效时间,当client从工作站注销后,所有的session ticketsession key都会被销毁。

大致过程如下:
Windows Kerberos 协议_经验分享_02
高清svg地址
pos文件地址

ticket-granting tickets

Kerberos协议设计之初,master key是使用用户提供的密码单向哈希得到的,client使用master key来解密从KDC获取到的session key

然而这样做存在的问题是每次clientKDC解密session key都需要使用master key,每次都让用户输入密码并产生master key显然是不现实的,那么就需要将master key存储在client中,但是由于用户的密码是一个long term key,这样就会产生key被窃取的问题。

Kerberos协议解决上述问题的方案是让clientKDC申请一个临时的key,,这个key只在当前logon session失效前有效(用户一旦注销,这个key就失效了),这个key被称作logon session key。当一个用户登录到client后,client回向KDC申请一个票据,这一步操作就跟clientKDC申请server的票据的操作是一样的,不同的是这里的server就是KDCKDC创建出一个logon session key和一个票据授予服务的票据。logon session key的一个拷贝被嵌入到**票据授予服务ticket**中,该ticket使用KDCmaster key进行加密。logon session key的另一份拷贝使用clientmaster key进行加密,然后KDCticketlogon session key一并发回给client

client收到KDC的响应之后,使用自己的master key解密出logon session key并将master key丢掉,因为以后都不会再使用master key了,以后client会直接使用logon session key来进行session key的解密操作,client将它的logon session keyticket-granting ticket放在安全缓存中。

ticket-granting ticket简称TGT。当clientDKC申请某个serverticket时,它将自己的authentication messageTGT一并发送给KDCKDC使用自己的master key解密TGT获得logon session key,使用logon session key加密session key

大致过程如下:
Windows Kerberos 协议_经验分享_03
高清svg地址

pos文件地址
总结下来,TGT就是为了避免clientmaster key被窃取而产生的,它的出现使得client由保存long term key变成了保存short term key

Kerberos 子协议