1. Introduction

当一个client需要从一个service端获取数据的情况, 难免需要通过网络传输数据, 以下是会遇到的问题:

  • 网络上传送的数据可能被他人窃听和篡改
  • service如何认定发送端是否为可信的client
  • service如何判断client是否有权限访问数据

最简单的解决方式是, service端保存所有client的用户名, 密钥, 以及对应的权限, client与service之间建立加密连接(如SSL). 问题在于, 一个复杂系统内一个client需要与多个service通信, 导致每个service都需要保留该client的用户名, 密钥及其权限; 一旦某个service数据泄露, 所有client的敏感信息都将泄漏.

Kerberos是一种网络身份验证协议, 旨在简化身份验证和授权. 以下是该协议的优点:

  • Security: Kerberos不会传输明文信息, 且通过有时效性的加密信息来验证用户身份, 即使信息被截获并破译也毫无意义.
  • Single Sign-On: Kerberos只要求验证client端身份时输入密码, 之后在一个realm中访问任何服务都无需密码. 这种单点登录的设计可简化流程.
  • Trusted third-party: Kerberos依赖一个名为KDC(Key Distribution Center, 密钥分发中心)的集中式身份验证服务器. 网络中所有设备都默认信任该服务器, 且所有身份验证信息都发往该服务器, 这样方式确保敏感信息无需存储到client或service中.
  • Mutual authentication: 在Kerberos中, client和service都必须通过身份验证, 这种双向认证大大降低了中间者攻击的概率.

2. Core Component of Kerberos

2.1 Key Distribution Center

KDC是Kerberos的核心, 其包含AS(Authentication Server)和TGS(Ticket Granting Service). 其主要功能为: 转发AS的消息, 授予client一个TGT(Ticket-Granting Ticket), 并将TGT交由TGS进行加密.

2.2 Ticket-Granting Ticket

Client通过身份验证后, KDC会授予client一个TGT. TGT包含client可访问的service列表, 访问有效期, 以及用于与client通信的session key(对称加密密钥).

2.3 Authentication Server

AS是Kerberos进行身份验证的第一步, client使用用户名和密码登录到AS进行身份验证. 完成验证后, AS会将用户名转发给KDC并授予TGT. 若无法验证身份, 则client无法与Kerberos中的其他服务进行交互.

2.4 Ticket Granting Service

TGS作为client与service的中介, 当client想要访问某个service时, client必须向TGS提交其TGT. TGS会对TGT进行验证, 并创建client与service共享的session key. 若TGS确认client的TGT包含对所需service的访问权限, 则授予client请求该service的权限.

3. Workflow

3.1 Login

用户使用用户名和密码登录Kerberos客户端, Kerberos客户端会将密码转换为一个secret key(称为client secret key)用于加密或解密信息.

3.2 Client Requests TGT from AS

Client向AS发送一个非加密文本, 其中包含:

  • client的用户名
  • 所需的service名称
  • client的IP地址
  • TGT有效期

AS通过数据库(通常是Active Directory)验证用户名是否存在. 若存在, 则返回以下两部分信息:

  • 第一部分信息由client secret key加密:
    • TGS名称或ID
    • 消息生成时间
    • TGT有效期
    • TGS session key(随机生成的临时对等密钥)
  • 第二部分为TGT, 由TGS secret key加密
    • 用户名或ID
    • TGS名称或ID
    • 消息生成时间
    • client的IP地址
    • TGS session key(与上一信息中的TGS session key相同)

需要注意的是, client secret key通常由用户名, client secret key, realm(域)构成的字符串通过哈希函数生成. 由于AS生成的client secret key与client自身持有的client secret key相同, 因此client可解码AS传回的第一部分信息; 但由于client不拥有TGS secret key, 因此无法解码第二部分信息. 该步骤可在不传输任何敏感信息的前提下验证用户名与密码, 并让client获得TGS session key.

3.3 Client Requests Service Ticket from TGS

身份验证完成后, client会向TGS发送请求, 其中包含以下三个部分信息:

  • TGT, 由TGS secret key加密
  • User Authenticator, 由TGS session key加密, 包含以下内容:
    • 用户名
    • 信息生成时间
  • 第三部分是非加密文本, 包含以下信息:
    • Service名称或ID
    • TGT有效期

由于TGS拥有TGS secret key, 因此可以解码TGT, 从而获取TGS session key; TGS再使用TGS session key解码user authenticator, 从而获取所有client传来的信息. 之后TGS会做以下验证:

  • 验证service是否存在
  • 验证TGT中的用户名与user authenticator中的用户名是否一致
  • 验证TGT中的消息生成时间与user authenticator中的消息生成时间是否在一定范围内
  • 验证当前消息的IP地址与TGT中的IP地址是否一致
  • 验证TGT是否过期

验证完毕后, TGS会向client回复以下两部分信息:

  • 第一部分信息由TGS session key加密:
    • Service的名字或ID
    • 消息生成时间
    • TGT有效期
    • Service session key(随机生成的临时对等密钥)
  • 第二部分称为ST(service ticket), 由service secret key加密
    • 用户名或ID
    • Service的名字或ID
    • 消息生成时间
    • client的IP地址
    • ST有效期
    • Service session key(与上一消息中的service session key相同)

Client收到TGS的回复后, 由于其拥有TGS session key, 因此可解码第一部分信息, 从而获取service session key. 该步骤让client成功从TGS端获取ST.

3.4 Client Contacts the Service

client获取ST后, 会向service发送两部分信息:

  • ST: 由service secret key加密
  • 新的user authenticator, 由service session key加密:
    • 用户名或ID
    • 消息生成时间

service收到消息后, 会使用service secret key解码ST, 并获取service session key, 从而解码user authenticator. 之后进行一系列验证:

  • 验证ST中的用户名与user authenticator中的用户名是否一致
  • 验证ST中的消息生成时间与user authenticator中的消息生成时间是否在一定范围内
  • 验证client的IP地址与ST中的IP地址是否一致
  • 验证ST是否有效

验证完毕后, service会向client回复信息, 该信息称为SA(servicee authenticator), 由service session key加密, 包含以下信息:

  • service名称或ID
  • 消息创建时间

client使用service session key解码后会验证service名称是否正确, 并确保消息生成时间在一定时间范围内. 至此, client与service完成了双向身份认证, 可进行后续通信.

4. Session keys and secret keys

以下是Kerberos出现的所有secret key:

  • client secret key: 用于加密TGS session key. client可生成该secret key, AS也会维护一个表格, 其包含每个用户名及其对应的secret key.
  • TGS secret key: 用于加密TGT. AS和TGS共享该secret key.
  • service secret key: 用于加密ST. TGS维护一个表格, 其包含每个service名称及其对应的secret key, 每个serice也会有各自的secret key.

以下是Kerberos出现的所有session key:

  • TGS session key: 由AS生成, client和TGS共享该session key, 用于加密client与TGS之间的信息
  • service session key: 由TGS生成, client和service共享该session key, 用于加密client与service之间的信息

5. Is Kerberos hackable?

尽管Kerberos是一种十分安全的协议, 但并不是不可破解的. 以下是五种攻击Kerberos系统的方法:

  • Pass-the-ticket: 黑客从client端窃取合法的TGT, 使用该TGT绕过身份验证, 冒充合法用户
  • Golden Ticket: 黑客攻击AS, 并向AS植入一个假用户, 之后使用假用户身份访问service
  • Silver Ticket: 黑客攻击service, 并获取其service secret key, 之后可使用伪造的ST绕过TGS直接与service通信
  • Brute force: 使用自动密码猜测器暴力查询某个用户的密码, 直到通过身份验证