跳到主要内容

3.2. The Client/Server Authentication Exchange (客户端/服务器认证交换)

3.2. The Client/Server Authentication Exchange (客户端/服务器认证交换)​

摘要​

消息方向消息类型章节
客户端到应用程序服务器KRB_AP_REQ5.5.1
[可选] 应用程序服务器到客户端KRB_AP_REP 或 KRB_ERROR5.5.2 或 5.9.1

客户端/服务器认证 (Client/Server, CS) 交换由网络应用程序用于向服务器认证客户端, 反之亦然.客户端必须 (MUST) 已经使用 AS 或 TGS 交换获取了服务器的凭证.

3.2.1. The KRB_AP_REQ Message (KRB_AP_REQ 消息)​

KRB_AP_REQ 包含应该 (SHOULD) 作为认证事务中第一条消息的一部分的认证信息.它包含票据、认证器和一些附加的簿记信息 (有关确切格式, 请参见第 5.5.1 节).票据本身不足以认证客户端, 因为票据以明文形式在网络上传递 (票据包含加密和未加密部分, 因此此处的明文是指整个单元, 可以从一条消息复制并在另一条消息中重放而无需任何密码学技能).认证器用于通过向服务器证明客户端知道票据的会话密钥从而有权使用票据来防止票据的无效重放.KRB_AP_REQ 消息在其他地方被称为 "认证头 (authentication header)".

3.2.2. Generation of a KRB_AP_REQ Message (生成 KRB_AP_REQ 消息)​

当客户端希望向服务器发起认证时, 它获取 (通过凭证缓存、AS 交换或 TGS 交换) 所需服务的票据和会话密钥.客户端可以 (MAY) 重新使用它持有的任何票据, 直到它们过期.要使用票据, 客户端从系统时间和其名称构造新的认证器, 并可选地从特定于应用程序的校验和、要在 KRB_SAFE 或 KRB_PRIV 消息中使用的初始序列号和/或要在针对此特定会话唯一的会话密钥协商中使用的会话子密钥构造.认证器禁止 (MUST NOT) 重新使用, 并且如果重放到服务器应该 (SHOULD) 被拒绝.请注意, 这会使基于不可靠传输的应用程序难以正确编码.如果传输可能传递重复的消息, 则必须 (MUST) 为每次重试生成新的认证器, 或者应用程序服务器必须 (MUST) 匹配请求和回复并重放第一个回复以响应检测到的重复.

如果要包含序列号, 它应该 (SHOULD) 随机选择, 以便即使在交换了许多消息之后, 它也不太可能与使用中的其他序列号发生冲突.

客户端可以 (MAY) 通过在消息的 ap-options 字段中设置适当的标志来指示相互认证或使用基于会话密钥的票据 (用于用户到用户认证, 请参见第 3.7 节) 的要求.

认证器在会话密钥中加密并与票据组合以形成 KRB_AP_REQ 消息, 然后将其与任何额外的特定于应用程序的信息一起发送到最终服务器.

3.2.3. Receipt of KRB_AP_REQ Message (接收 KRB_AP_REQ 消息)​

认证基于服务器当前的时间 (时钟必须 (MUST) 松散同步)、认证器和票据.可能会发生几个错误.如果发生错误, 服务器应该用 KRB_ERROR 消息回复客户端.如果应用程序协议不接受其原始形式, 则此消息可以 (MAY) 封装在应用程序协议中.错误消息的格式在第 5.9.1 节中描述.

验证认证信息的算法如下.如果消息类型不是 KRB_AP_REQ, 服务器返回 KRB_AP_ERR_MSG_TYPE 错误.如果 KRB_AP_REQ 中的票据指示的密钥版本不是服务器可以使用的版本 (例如, 它指示旧密钥, 而服务器不再拥有旧密钥的副本), 则返回 KRB_AP_ERR_BADKEYVER 错误.如果在 ap-options 字段中设置了 USE-SESSION-KEY 标志, 它向服务器指示正在使用用户到用户认证, 并且票据在服务器的 TGT 的会话密钥中加密, 而不是在服务器的密钥中加密.有关用户到用户认证对 Kerberos 协议中所有消息的影响的更完整描述, 请参见第 3.7 节.

因为服务器可能在多个域中注册, 在每个域中具有不同的密钥, 所以 KRB_AP_REQ 中票据的未加密部分中的 srealm 字段用于指定服务器应使用哪个密钥来解密该票据.如果服务器没有适当的密钥来解密票据, 则返回 KRB_AP_ERR_NOKEY 错误代码.

使用票据指定的服务器密钥版本解密票据.如果解密例程检测到票据的修改 (每个加密系统必须 (MUST) 提供保护措施以检测修改的密文), 则返回 KRB_AP_ERR_BAD_INTEGRITY 错误 (很可能使用不同的密钥进行加密和解密).

使用从解密的票据中提取的会话密钥解密认证器.如果解密显示它已被修改, 则返回 KRB_AP_ERR_BAD_INTEGRITY 错误.将票据中的客户端的名称和域与认证器中的相同字段进行比较.如果它们不匹配, 则返回 KRB_AP_ERR_BADMATCH 错误; 通常这是由客户端错误或试图攻击引起的.然后在票据中的地址 (如果有) 中搜索与操作系统报告的客户端地址匹配的地址.如果未找到匹配项或服务器坚持票据地址但票据中不存在地址, 则返回 KRB_AP_ERR_BADADDR 错误.如果本地 (服务器) 时间和认证器中的客户端时间相差超过允许的时钟偏移 (例如, 5 分钟), 则返回 KRB_AP_ERR_SKEW 错误.

除非应用程序服务器提供自己的合适方法来防止重放 (例如, 服务器在认证后发起的挑战-响应序列, 或使用服务器生成的加密子密钥), 否则服务器必须 (MUST) 利用重放缓存来记住在允许的时钟偏移内呈现的任何认证器.在消除此缓存之前, 建议仔细分析应用程序协议和实现.重放缓存将至少存储服务器名称以及客户端名称、时间和来自最近看到的认证器的微秒字段, 如果找到匹配的元组, 则返回 KRB_AP_ERR_REPEAT 错误.请注意, 此处的拒绝仅限于来自同一主体到同一服务器的认证器.如果时间和微秒字段恰好与某个其他客户端的认证器匹配, 则与同一服务器主体通信的其他客户端主体不应拒绝其认证器.

如果服务器失去了在允许的时钟偏移内呈现的认证器的跟踪, 它必须 (MUST) 拒绝所有请求, 直到时钟偏移间隔过去, 从而保证任何丢失或重放的认证器将落在允许的时钟偏移之外并且不能再成功重放.如果不这样做, 攻击者可以通过记录通过网络发送到服务器的票据和认证器, 并在导致服务器失去对最近看到的认证器的跟踪的事件之后重放它们来破坏认证.

实现说明: 如果客户端向 KDC 生成具有相同时间戳 (包括微秒字段) 的多个请求, 则收到的除第一个请求之外的所有请求都将被拒绝为重放.例如, 如果客户端时钟的分辨率太粗, 这可能会发生.客户端实现应该 (SHOULD) 确保时间戳不被重用, 可能通过在时钟为多个请求返回相同时间时递增时间戳中的微秒字段.

如果多个服务器 (例如, 一台机器上的不同服务, 或在多台机器上实现的单个服务) 共享一个服务主体 (我们通常不推荐这种做法, 但我们承认在某些情况下会使用它), 则它们必须 (MUST) 共享此重放缓存, 或者应用程序协议必须 (MUST) 设计为消除对它的需要.请注意, 这适用于所有服务.如果任何应用程序协议没有内置重放保护, 则与此类服务一起使用的认证器稍后可以重放到具有相同服务主体但没有重放保护的不同服务, 如果前者没有在公共重放缓存中记录认证器信息.

如果在认证器中提供了序列号, 服务器将其保存以供以后在处理 KRB_SAFE 和/或 KRB_PRIV 消息时使用.如果存在子密钥, 服务器要么将其保存以供以后使用, 要么使用它来帮助生成其自己选择的子密钥以在 KRB_AP_REP 消息中返回.

服务器计算票据的年龄: 本地 (服务器) 时间减去票据内的开始时间.如果开始时间比当前时间晚超过允许的时钟偏移, 或者如果在票据中设置了 INVALID 标志, 则返回 KRB_AP_ERR_TKT_NYV 错误.否则, 如果当前时间比结束时间晚超过允许的时钟偏移, 则返回 KRB_AP_ERR_TKT_EXPIRED 错误.

如果所有这些检查都成功而没有错误, 则服务器确信客户端拥有票据中命名的主体的凭证, 因此客户端已被认证到服务器.

通过这些检查仅提供命名主体的认证; 它并不意味着授权使用命名服务.应用程序必须 (MUST) 根据用户的认证名称、请求的操作、本地访问控制信息 (例如 .k5login 或 .k5users 文件中包含的信息) 以及可能的单独的分布式授权服务来做出单独的授权决定.

3.2.4. Generation of a KRB_AP_REP Message (生成 KRB_AP_REP 消息)​

通常, 客户端的请求将在同一消息中包含认证信息和其初始请求, 并且服务器无需显式回复 KRB_AP_REQ.然而, 如果正在执行相互认证 (不仅将客户端认证到服务器, 而且还将服务器认证到客户端), 则 KRB_AP_REQ 消息将在其 ap-options 字段中设置 MUTUAL-REQUIRED, 并且需要 KRB_AP_REP 消息作为响应.与错误消息一样, 如果应用程序协议不接受其 "原始" 形式, 则此消息可以 (MAY) 封装在应用程序协议中.回复中使用的时间戳和微秒字段必须 (MUST) 是客户端的时间戳和微秒字段 (如认证器中提供的那样).如果要包含序列号, 它应该 (SHOULD) 如上所述为认证器随机选择.如果服务器希望协商不同的子密钥, 则可以 (MAY) 包含子密钥.KRB_AP_REP 消息在从票据中提取的会话密钥中加密.

请注意, 在 Kerberos 版本 4 协议中, 回复中的时间戳是客户端的时间戳加一.这在版本 5 中不是必需的, 因为版本 5 消息的格式化方式使得即使在加密形式下也不可能通过明智的消息手术创建回复而不知道适当的加密密钥.

3.2.5. Receipt of KRB_AP_REP Message (接收 KRB_AP_REP 消息)​

如果返回 KRB_AP_REP 消息, 客户端使用从为服务器获取的凭证中的会话密钥解密消息, 并验证时间戳和微秒字段是否与它发送到服务器的认证器中的那些匹配.如果它们匹配, 则客户端确信服务器是真实的.序列号和子密钥 (如果存在) 将保留以供以后使用.(请注意, 对于加密 KRB_AP_REP 消息, 即使子会话密钥存在于认证中, 也不使用子会话密钥.)

3.2.6. Using the Encryption Key (使用加密密钥)​

在 KRB_AP_REQ/KRB_AP_REP 交换发生后, 客户端和服务器共享一个可由应用程序使用的加密密钥.在某些情况下, 此会话密钥的使用将在协议中是隐式的; 在其他情况下, 使用方法必须从几个备选方案中选择.应用程序可以 (MAY) 根据票据中的会话密钥以及 KRB_AP_REP 消息和认证器中的子密钥来选择要用于 KRB_PRIV、KRB_SAFE 或其他特定于应用程序的用途的实际加密密钥.协议的实现可以 (MAY) 提供例程来基于会话密钥和随机数选择子密钥, 并生成要在 KRB_AP_REP 消息中返回的协商密钥.

为了减轻客户端上随机数生成失败的影响, 强烈建议应用程序为后续使用派生的任何密钥都包含从票据中携带的 KDC 生成的会话密钥派生的完整密钥熵.我们将如何使用密钥的协议协商 (例如, 用于选择加密或校验和类型) 留给应用程序程序员.Kerberos 协议不约束实现选项, 但以下是如何完成此操作的示例.

应用程序选择用于后续完整性和隐私保护的密钥的一种方法是客户端在认证器的子密钥字段中提出密钥.然后服务器可以使用客户端提出的密钥作为输入来选择密钥, 在应用程序回复的子密钥字段中返回新的子密钥.然后可以将此密钥用于后续通信.

对于单向和相互认证交换, 对等方应注意不要在没有适当保证的情况下向彼此发送敏感信息.特别是, 需要隐私或完整性的应用程序应该 (SHOULD) 使用从服务器到客户端的 KRB_AP_REP 响应来确保客户端和服务器对等方的身份.如果应用程序协议需要其消息的隐私, 它可以使用 KRB_PRIV 消息 (第 3.5 节).KRB_SAFE 消息 (第 3.4 节) 可用于确保完整性.