Skip to main content

10. Authentication and Message-Integrity Mechanisms (认证和消息完整性机制)

本节定义了 STUN 的两种机制,客户端和服务器可以使用这些机制来提供认证和消息完整性; 这两种机制称为短期凭证机制 (short-term credential mechanism) 和长期凭证机制 (long-term credential mechanism)。这两种机制都是可选的,每个用法必须 (must) 指定是否以及何时使用这些机制。因此,客户端和服务器都将根据适用的用法知识知道要遵循哪种机制 (如果有)。例如,支持 ICE 的公共互联网上的 STUN 服务器将没有认证,而支持连接性检查的代理中的 STUN 服务器功能将使用短期凭证。第3节给出了这两种机制的概述。

每种机制都指定了使用该机制所需的额外处理,扩展了第7节中指定的处理。额外的处理发生在三个不同的地方: 在形成消息时、在执行基本检查后立即接收消息时,以及在对错误响应进行详细处理时。

10.1. Short-Term Credential Mechanism (短期凭证机制)

短期凭证机制假设在 STUN 事务之前,客户端和服务器已使用其他协议交换了用户名和密码形式的凭证。此凭证是有时间限制的。时间限制由用法定义。

例如,在 ICE 用法 [MMUSIC-ICE] 中,两个端点使用带外信令来协商用户名和密码,并且此用户名和密码在媒体会话期间适用。

此凭证用于在每个请求和许多响应中形成消息完整性检查。与长期机制不同,没有质询和响应; 因此,通过凭证的有时间限制性质来防止重放。

10.1.1. Forming a Request or Indication (形成请求或指示)

对于请求或指示消息,代理必须 (MUST) 在消息中包含 USERNAME 和 MESSAGE-INTEGRITY 属性。MESSAGE-INTEGRITY 属性的 HMAC 按照第 15.4 节中的描述计算。请注意,密码从未包含在请求或指示中。

10.1.2. Receiving a Request or Indication (接收请求或指示)

在代理完成消息的基本处理后,代理按照指定的顺序执行以下列出的检查:

  • 如果消息不包含 MESSAGE-INTEGRITY 和 USERNAME 属性:

    • 如果消息是请求,服务器必须 (MUST) 使用错误响应拒绝该请求。此响应必须 (MUST) 使用错误码 400 (Bad Request)。

    • 如果消息是指示,代理必须 (MUST) 静默丢弃该指示。

  • 如果 USERNAME 不包含服务器当前有效的用户名值:

    • 如果消息是请求,服务器必须 (MUST) 使用错误响应拒绝该请求。此响应必须 (MUST) 使用错误码 401 (Unauthorized)。

    • 如果消息是指示,代理必须 (MUST) 静默丢弃该指示。

  • 使用与用户名关联的密码,按照第 15.4 节中的描述计算消息完整性的值。如果结果值与 MESSAGE-INTEGRITY 属性的内容不匹配:

    • 如果消息是请求,服务器必须 (MUST) 使用错误响应拒绝该请求。此响应必须 (MUST) 使用错误码 401 (Unauthorized)。

    • 如果消息是指示,代理必须 (MUST) 静默丢弃该指示。

如果这些检查通过,代理继续处理请求或指示。服务器生成的任何响应必须 (MUST) 包含 MESSAGE-INTEGRITY 属性,使用用于认证请求的密码计算。响应禁止 (MUST NOT) 包含 USERNAME 属性。

如果任何检查失败,服务器禁止 (MUST NOT) 在错误响应中包含 MESSAGE-INTEGRITY 或 USERNAME 属性。这是因为,在这些失败情况下,服务器无法确定计算 MESSAGE-INTEGRITY 所需的共享密钥。

10.1.3. Receiving a Response (接收响应)

客户端在响应中查找 MESSAGE-INTEGRITY 属性。如果存在,客户端使用为请求使用的相同密码,按照第 15.4 节中的定义计算响应的消息完整性。如果结果值与 MESSAGE-INTEGRITY 属性的内容匹配,则响应被视为已认证。如果值不匹配,或者 MESSAGE-INTEGRITY 不存在,则必须 (MUST) 丢弃响应,就像从未收到一样。这意味着,如果适用,重传将继续。

10.2. Long-Term Credential Mechanism (长期凭证机制)

长期凭证机制依赖于长期凭证,即客户端和服务器之间共享的用户名和密码形式。该凭证被视为长期凭证,因为假设它是为用户提供的,并且在用户不再是系统的订户或被更改之前一直有效。这基本上是传统的授予用户的 "登录" 用户名和密码。

由于这些用户名和密码预期在较长时间内有效,因此以摘要质询的形式提供重放防护。在此机制中,客户端最初发送请求,而不提供任何凭证或任何完整性检查。服务器拒绝此请求,向用户提供领域 (realm,用于指导用户或代理选择用户名和密码) 和随机数 (nonce)。随机数提供重放保护。它是服务器选择的 cookie,以某种方式编码以指示有效期或其有效的客户端身份。客户端重试请求,这次包括其用户名和领域,并回显服务器提供的随机数。客户端还包括消息完整性,它提供对整个请求的 HMAC,包括随机数。服务器验证随机数并检查消息完整性。如果匹配,则请求已认证。如果随机数不再有效,则被视为 "过时",服务器拒绝请求,提供新的随机数。

在对同一服务器的后续请求中,客户端重用它之前使用的随机数、用户名、领域和密码。通过这种方式,后续请求不会被拒绝,直到服务器使随机数无效,在这种情况下,拒绝向客户端提供新的随机数。

请注意,长期凭证机制不能用于保护指示,因为指示不能被质询。使用指示的用法必须使用短期凭证或省略它们的认证和消息完整性。

由于长期凭证机制容易受到离线字典攻击,部署应该 (SHOULD) 使用难以猜测的密码。在凭证不是由用户输入而是在设备配置期间放置在客户端设备上的情况下,密码应该 (SHOULD) 具有至少 128 位的随机性。在凭证由用户输入的情况下,它们应该遵循有关密码结构的当前最佳实践。

10.2.1. Forming a Request (形成请求)

在形成请求时有两种情况。在第一种情况下,这是客户端向服务器发出的第一个请求 (由其 IP 地址和端口标识)。在第二种情况下,客户端在先前的请求/响应事务成功完成后提交后续请求。作为 401 或 438 错误响应的结果形成请求在第 10.2.3 节中介绍,不被视为 "后续请求",因此不使用第 10.2.1.2 节中描述的规则。

10.2.1.1. First Request (第一个请求)

如果客户端尚未与服务器完成成功的请求/响应事务 (如果使用第9节的 DNS 过程,则由主机名标识,否则如果不使用,则由 IP 地址标识),它应该 (SHOULD) 省略 USERNAME、MESSAGE-INTEGRITY、REALM 和 NONCE 属性。换句话说,第一个请求的发送就好像没有应用认证或消息完整性一样。

10.2.1.2. Subsequent Requests (后续请求)

一旦请求/响应事务成功完成,服务器将向客户端提供领域和随机数,并且客户端将选择用于认证的用户名和密码。客户端应该 (SHOULD) 缓存用户名、密码、领域和随机数,以便与服务器的后续通信。当客户端发送后续请求时,它应该 (SHOULD) 使用这些缓存值包含 USERNAME、REALM 和 NONCE 属性。它应该 (SHOULD) 包含 MESSAGE-INTEGRITY 属性,使用缓存的密码按照第 15.4 节中的描述计算。

10.2.2. Receiving a Request (接收请求)

在服务器完成请求的基本处理后,它按照指定的顺序执行以下列出的检查:

  • 如果消息不包含 MESSAGE-INTEGRITY 属性,服务器必须 (MUST) 生成错误码为 401 (Unauthorized) 的错误响应。此响应必须 (MUST) 包含 REALM 值。推荐 (RECOMMENDED) REALM 值为 STUN 服务器提供商的域名。响应必须 (MUST) 包含由服务器选择的 NONCE。响应不应该 (SHOULD NOT) 包含 USERNAME 或 MESSAGE-INTEGRITY 属性。

  • 如果消息包含 MESSAGE-INTEGRITY 属性,但缺少 USERNAME、REALM 或 NONCE 属性,服务器必须 (MUST) 生成错误码为 400 (Bad Request) 的错误响应。此响应不应该 (SHOULD NOT) 包含 USERNAME、NONCE、REALM 或 MESSAGE-INTEGRITY 属性。

  • 如果 NONCE 不再有效,服务器必须 (MUST) 生成错误码为 438 (Stale Nonce) 的错误响应。此响应必须 (MUST) 包含 NONCE 和 REALM 属性,不应该 (SHOULD NOT) 包含 USERNAME 或 MESSAGE-INTEGRITY 属性。服务器可以使随机数无效以提供额外的安全性。有关指南,请参阅 [RFC2617] 的第 4.3 节。

  • 如果 USERNAME 属性中的用户名无效,服务器必须 (MUST) 生成错误码为 401 (Unauthorized) 的错误响应。此响应必须 (MUST) 包含 REALM 值。推荐 (RECOMMENDED) REALM 值为 STUN 服务器提供商的域名。响应必须 (MUST) 包含由服务器选择的 NONCE。响应不应该 (SHOULD NOT) 包含 USERNAME 或 MESSAGE-INTEGRITY 属性。

  • 使用与 USERNAME 属性中的用户名关联的密码,按照第 15.4 节中的描述计算消息完整性的值。如果结果值与 MESSAGE-INTEGRITY 属性的内容不匹配,服务器必须 (MUST) 使用错误响应拒绝该请求。此响应必须 (MUST) 使用错误码 401 (Unauthorized)。它必须 (MUST) 包含 REALM 和 NONCE 属性,不应该 (SHOULD NOT) 包含 USERNAME 或 MESSAGE-INTEGRITY 属性。

如果这些检查通过,服务器继续处理请求。服务器生成的任何响应 (除上述情况外) 必须 (MUST) 包含 MESSAGE-INTEGRITY 属性,使用用于认证请求的用户名和密码计算。REALM、NONCE 和 USERNAME 属性不应该 (SHOULD NOT) 包含。

10.2.3. Receiving a Response (接收响应)

如果响应是错误码为 401 (Unauthorized) 的错误响应,客户端应该 (SHOULD) 使用新事务重试请求。此请求必须 (MUST) 包含 USERNAME,由客户端确定为来自错误响应的 REALM 的适当用户名。请求必须 (MUST) 包含 REALM,从错误响应复制。请求必须 (MUST) 包含 NONCE,从错误响应复制。请求必须 (MUST) 包含 MESSAGE-INTEGRITY 属性,使用与 USERNAME 属性中的用户名关联的密码计算。如果客户端没有更改 USERNAME 或 REALM 或其关联密码 (与之前的尝试相比),则禁止 (MUST NOT) 执行此重试。

如果响应是错误码为 438 (Stale Nonce) 的错误响应,客户端必须 (MUST) 重试请求,使用 438 (Stale Nonce) 响应中提供的新 NONCE。此重试还必须 (MUST) 包含 USERNAME、REALM 和 MESSAGE-INTEGRITY。

客户端在响应中查找 MESSAGE-INTEGRITY 属性 (成功或失败)。如果存在,客户端使用为请求使用的相同密码,按照第 15.4 节中的定义计算响应的消息完整性。如果结果值与 MESSAGE-INTEGRITY 属性的内容匹配,则响应被视为已认证。如果值不匹配,或者 MESSAGE-INTEGRITY 不存在,则必须 (MUST) 丢弃响应,就像从未收到一样。这意味着,如果适用,重传将继续。