Kerberos原理
1. 什么是 Kerberos
kerberos 是 Active Directory 网络中域帐户的首选身份验证协议(它不能在工作组中使用),它由 kerberos SSP 实现。Kerberos 的细节在 RFC 4120 中进行了描述,在 Active Directory 中使用的扩展记录在 MS-KILE文档中。Kerberos 侧重于使用称为“票据”的令牌,它允许根据主体对用户进行身份验证。
2. Kerberos 相关
2.1. 传输层:
Kerberos 使用 UDP 或 TCP 作为传输协议,以明文形式发送数据;因此,Kerberos 负责提供加密
- Kerberos 使用的端口是UDP/88和TCP/88,
- Kerberos 密钥分发中心 (KDC) 在该端口上侦听票证请求。
2.2. 代理
几个代理一起在Kerberos中提供身份验证:
- 希望访问服务的客户端或用户
- AP(Application Server)它提供用户所需的服务
- KDC (Key Distribution Center),是Kerberos的主要服务,负责发行票据,安装在DC(域控制器)上;它由颁发 TGT 的 AS(身份验证服务)支持(Key Distribution Center),是Kerberos的主要服务
3. Kerberos 认证过程中的票据
3.1. TGT(Ticket Granting Ticket)
用途:TGT 是用户在登录时首先从 Kerberos 认证服务器(KDC)获取的票据。它是用户的认证凭证,允许用户向 TGS(票据授予服务)请求服务票据(ST)。
加密方式:TGT 使用 KDC 的密钥加密,KDC(即 Kerberos 认证服务器)是受信任的,并持有加密 TGT 的密钥。
生命周期:TGT 通常有一定的有效期(例如 10 小时),在此期间,用户不需要重新输入密码即可请求服务票据。
3.2. TGS(Ticket Granting Service)
用途:TGS 是 Kerberos 的一个服务,它根据用户的 TGT 向用户提供具体的服务票据(ST)。如果用户想要访问某个特定的服务(例如文件共享、Web 服务等),他会使用 TGT 向 TGS 请求 ST。
加密方式:TGS 使用特定服务的密钥加密服务票据(ST),确保只有该服务才能解密并使用这个票据进行身份验证。
3.3. ST(Service Ticket):
用途:ST 是用户请求访问特定服务时,TGS 返回给用户的票据。用户通过将 ST 发送给目标服务来证明其身份,服务可以解密 ST 以验证用户的身份。
加密方式:ST 使用目标服务的密钥加密。服务可以使用自己的密钥来解密 ST 并验证用户的身份。
4. 什么是PAC
在 Windows 环境下,Kerberos 身份验证不仅仅验证用户的身份,还涉及用户的授权信息。PAC 就是存储用户权限信息的容器,它包含了用户所属的组、访问权限等数据。
4.1. PAC 结构
PAC 作为 Kerberos 服务票据(TGS)的一部分,由 KDC(Key Distribution Center) 生成并附加到服务票据(ST)中。PAC 主要包括以下内容
- 用户的组成员信息(Group Membership)
- 用户的权限信息(User Permissions)
- 用户的 SID(Security Identifier)
- 用户账户的其它信息
4.2. PAC 的生成与传递
- 当用户首次请求访问服务时,Kerberos 认证服务器会为用户生成一个 TGT,并在后续的请求中附加 PAC
- 用户在凭借有效的 TGT 请求 TGS 时,TGS 会将 PAC 附加到 ST(服务票据)中返回给用户。
- 用户凭借 ST 向目标服务发起请求时,目标服务会从 ST 中提取 PAC,并解析其中的权限信息,来验证用户是否具备访问目标资源的权限。
4.3. PAC 的安全性
- 签名:PAC 被 KDC 用其密钥进行签名,以确保其未被篡改。目标服务使用 KDC 公钥进行验证,确保 PAC 中的内容是可信的。
- 完整性:为了防止 PAC 在传输过程中被篡改,通常会使用加密保护 PAC 的完整性
几个用于验证 PAC 和票证数据完整性的签名
服务器签名:使用用于加密票证的相同密钥创建的 PAC 内容签名
KDC 签名:使用 KDC 密钥创建的服务器签名的签名,可用于检查 PAC 是否由 KDC 创建并防止票据击
票据签名:使用 KDC 密钥创建的票据内容的签名,最近引入了此签名以防止青铜位攻击(CVE-2020-17049)
5. Kerberos 常用的不同种类消息
- KRB_AS_REQ:用于向 KDC 请求 TGT
- KRB_AS_REP:用于通过 KDC 交付 TGT
- KRB_TGS_REQ:用于使用 TGT 向 KDC 请求 TGS
- KRB_TGS_REP:用于通过 KDC 交付 TGS
- KRB_AP_REQ:用于使用 TGS 针对服务对用户进行身份验证
- KRB_AP_REP:(可选)服务用于向用户标识自己
- KRB_ERROR:用于传达错误情况的消息
此外,即使它不是 Kerberos 的一部分,而是 NRPC的一部分,AP 也可以选择使用 KERB_VERIFY_PAC_REQUEST 消息向 KDC 发送 PAC 的签名,并验证它是否正确
6. Kerveros认证流程
6.1. KRB_AS_REQ:
首先,用户必须从 KDC 申请一个 TGT。为此,必须发送 KRB_AS_REQ:

KRB_AS_REQ具有以下字段:
- 带有客户端密钥的加密时间戳,用于验证用户身份并防止重放攻击
- 认证用户的用户名
- 与krbtgt帐户关联的服务SPN
- 由用户生成的Nonce
注意:加密的时间戳只有在用户需要预认证时才需要,比较常见,除非在用户帐户中设置了 DONT_REQ_PREAUTH 标志
6.2. KRB_AS_REP:
接收到请求后,KDC通过解密时间戳验证用户身份,如果消息是正确的话,那么它会响应一个KRB_AS_REP:

KRB_AS_REP 包含以下信息:
- 用户名
- TGT、其中包括:用户名、会话密钥、TGT 的有效期、具有用户权限的PAC,由 KDC 签名
- 一些使用用户密钥的加密数据,其中包括:会话密钥、TGT 的有效期、用户的 nonce,以防止重放攻击
完成后,用户就已经拥有 TGT,可用于请求 TGS,然后访问服务。
6.3. KRB_TGS_REQ:
了请求 TGS,必须向 KDC 发送 KRB_TGS_REQ 消息:

KRB_TGS_REQ包括:
- 使用会话密钥加密的数据:用户名、时间戳
- TGT
- 请求服务的SPN
- 用户生成的Nonce
6.4. KRB_TGS_REP
收到 KRB_TGS_REQ 消息后,KDC 在 KRB_TGS_REP 内部返回一个 TGS :

KRB_TGS_REP 包括:
- 用户名
- TGS,其中包含:服务会话密钥、用户名、TGS的有效期、具有用户权限的 PAC,由 KDC 签名
- 使用会话密钥加密的数据:服务会话密钥、TGS的有效期、用户 nonce,防止重放攻击
6.5. KRB_AP_REQ
最后,如果一切顺利,用户已经拥有了一个有效的 TGS 来与服务交互,为了使用它,用户必须向 AP 发送一条KRB_AP_REQ消息:

KRB_AP_REQ包括:
- TGS
- 使用服务会话密钥加密的数据:
- 用户名
- 时间戳,避免重放攻击
之后,如果用户权限正确,就可以访问服务。