一开始,当用户登录到他们的工作站的时候,一个authentication server request(AS-REQ)被发送给域控制器。AS-REQ包括一个时间戳,这个时间戳是由用户密码和用户名哈希而成。
当域控制器收到这个请求后,它在ntds.dit文件里查询密码哈希和指定用户的对应关系,同时尝试解密时间戳。如果解密进程是成功的并且时间戳不是重复的,这次认证就被认为是成功的。(如果时间戳是重复的,就表明存在潜在的重放攻击)
接下来,域控制器回复客户端,使用authentication server replay(AS-REP)。由于Kerberos是一个无状态的协议,AS-REP包含一个session key和一个ticket granting ticket(TGT)。session key被加密,使用用户密码的哈希,而且可以被客户端解密和重复使用。TGT包含的信息有用户、域、一个时间戳、客户端IP地址和session key。
为了避免被篡改,TGT被加密了,使用一个只有KDC知道的密钥(krbtgt账户的NTLM哈希)而且不能被客户端解密。一旦客户端收到了session key和TGT,KDC就认为客户端认证完成了。默认情况下,TGT在重新生成之后的十小时内有效。重新生成不需要用户重新输入密码。
当用户希望访问域中的资源的时候,比如一个网络共享或者邮箱,它必须重新联系KDC。
这时,客户端构建一个ticket granting service request(TGS-REQ)包,它包括了当前用户和一个使用session key加密的时间戳,以及资源的名称和加密的TGT。
接下来,在KDC上的ticket-granting服务收到TGS-REQ,并且如果资源在域中是存在的,TGT将被解密,使用只有KDC知道的密钥。session key将从TGT中被提取,并被用来加密请求中的用户名和时间戳。这时,KDC会执行这几项检查:
- TGT必须具有有效的时间戳。
- TGS-REQ中的用户名必须和TGT中的用户名匹配。
- 客户端的IP地址需要和TGT的IP地址一致。
如果这个认证过程是成功的,ticket-granting服务会回复给客户端一个ticket granting server replay(TGS-REP)。这个包包含了三个部分:
- 被授权访问服务的名称。
- 一个被用于客户端和服务的session key。
- 一个包含用户名和组成员以及新创建的session key的service ticket。
service ticket的服务名称和session key都是被加密的,使用和TGT创建相关联的原始session key进行加密。service ticket是被加密的,使用向此服务注册过的服务账户的密码哈希进行加密。
一旦KDC上的认证流程完成,并且客户端得到了session key和service ticket,服务认证就会开始。
一开始,客户端向应用服务器发送application request(AP-REQ),这包含用户名和加密的时间戳以及service ticket本身,其中加密是使用与service ticket相关联的session key加密的。
应用服务器使用服务账户的密码哈希解密service ticket,并且提取用户名和session key。然后它使用后者从AP-REQ中解密用户名。如果AP-REQ用户名和从service ticket中解密的一致,请求就被接收。在被授权访问之前,服务器检查在service ticket中被提供的组成员,并给用户分配合适的权限,在这之后用户将可以访问请求的服务。
这个协议看起来好像是复杂的甚至是令人费解的,但它的设计目的就是为了缓解各种网络攻击并防止虚假凭证的使用。
(注:1. 本文未提及加密算法;2. 请勿完全复用本文,因为其内容在查重程序中一般会被作为文献;3. 转载请标明本文链接https://blog.csdn.net/qq_43750882/article/details/140082843。)