微信搜索我吃你家米了关注公众号

Windows Kerberos 协议_身份认证

备注:下面的示例图中的ticket都做了简化,真正的ticket结构要更加复杂

基本概念

基于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 协议_身份认证_02

session key的分发

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

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

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

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

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

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

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

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

session tickets

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

​server​​​收到来自​​client​​​的数据包之后,使用自己的​​master key​​​解密​​session ticket​​​,获取到​​session key​​​,然后使用​​session key​​​解密​​authenticator​​​获取到​​authentication message​​​,如果​​authentication message​​​正常(可读),则​​client​​​身份认证成功,然后​​server​​​将​​authentication message​​​中的​​timestamp​​​使用​​session key​​​进行加密并发回给​​client​​​,​​client​​​解密并和**初始​​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 ticket​​​和​​session key​​都会被销毁。

大致过程如下:

Windows Kerberos 协议_客户端_03

​高清svg地址​

​pos文件地址​

ticket-granting tickets

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

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

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

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

​ticket-granting ticket​​​简称​​TGT​​​。当​​client​​​向​​DKC​​​申请某个​​server​​​的​​ticket​​​时,它将自己的​​authentication message​​​和​​TGT​​​一并发送给​​KDC​​​,​​KDC​​​使用自己的​​master key​​​解密​​TGT​​​获得​​logon session key​​​,使用​​logon session key​​​加密​​session key​

大致过程如下:

Windows Kerberos 协议_身份认证_04

​高清svg地址​

​pos文件地址​

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

Kerberos 子协议