非官方中文译本声明:本页为 IETF RFC 5802《Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms》中文译本,由 ztpop.net 整理翻译,仅供学习参考。RFC 文档由 IETF 发布,受 BCP 78 与 IETF 信托法律条款约束;本译本保留原文编号与结构,权威性以英文原文为准。英文原文见 rfc-editor.org/rfc/rfc5802

RFC 5802:SCRAM SASL 机制

摘要

互联网应用协议最广泛部署和使用的安认证机制,是通过由传输层安全(TLS)保护的信道来传输明文口令。该机制存在一些显著的安全隐患,而借助受 TLS 保护的质询响应认证机制本可解决这些隐患。遗憾的是,目前处于标准轨道上的质询响应机制均未能满足大规模部署所需的各项要求,仅在有限的范围内取得了成功。

本规范描述了一系列简单认证与安全层(SASL;RFC 4422)认证机制,称为加盐质询响应认证机制(Salted Challenge Response Authentication Mechanism,SCRAM),它既能消除上述安全隐患,又能满足可部署性要求。当与 TLS 或等效的安全层结合使用时,该系列中的某个机制可以改善应用协议认证的现状,并为未来的应用协议标准提供一个合适的"强制实现(mandatory-to-implement)"机制选项。

本备忘录的状态

这是一份互联网标准跟踪(Standards Track)文档。

本文档是互联网工程任务组(IETF)的成果,代表了 IETF 社区的共识,已通过公众评审,并经互联网工程指导组(IESG)批准发布。有关互联网标准的更多信息,见 RFC 5741 第 2 节。

关于本文档当前状态、任何勘误以及如何提供反馈的信息,可在 http://www.rfc-editor.org/info/rfc5802 获取。

Copyright (c) 2010 IETF 信托及被列为文档作者的个人。保留所有权利。

本文档受 BCP 78 以及 IETF 信托的《IETF 文档相关法律规定》(http://trustee.ietf.org/license-info)约束,以本文档发布之日生效的版本为准。请仔细审阅这些文档,因为它们描述了您就本文档所享有的权利与限制。从本文档中提取的代码组件必须包含《简化 BSD 许可证》文本(见信托法律条款第 4.e 节),并如《简化 BSD 许可证》所述"不提供任何担保"。

目录

1. 引言

本规范描述了一系列称为加盐质询响应认证机制(SCRAM)的认证机制,它满足了比以往尝试更广泛地部署质询响应机制的各项要求(见附录 A 与附录 B)。当与传输层安全(TLS;见 [RFC5246])或等效的安全层结合使用时,该系列中的某个机制可以改善应用协议认证的现状,并为未来的应用协议标准提供一个合适的"强制实现"机制选项。

为求简洁,该系列机制目前不包含安全层协商 [RFC4422]。它意在与外部安全层(如 TLS 或 SSH 所提供的)结合使用,并可选用对外部安全层的信道绑定 [RFC5056]。

本文档将 SCRAM 规定为一种纯简单认证与安全层(SASL)[RFC4422] 机制,但它也符合称为"GS2" [RFC5801] 的、SASL 与通用安全服务应用程序接口(GSS-API)之间新的桥接规范。这意味着本文档同时定义了一个 SASL 机制和一个 GSS-API 机制。

SCRAM 提供以下协议特性:

另有独立文档定义了标准的 LDAPv3 [RFC4510] 属性,使得 SCRAM 认证信息能够存储于 LDAP 中,见 [RFC5803]。

关于为何其他质询响应机制被认为不够充分的深入讨论,见附录 A。关于本机制设计背后动机的更多信息,见附录 B。

2. 本文档使用的约定

本文档中的关键词"MUST(必须)"、"MUST NOT(不得)"、"REQUIRED(要求)"、"SHALL(应)"、"SHALL NOT(不应)"、"SHOULD(应该)"、"SHOULD NOT(不应该)"、"RECOMMENDED(推荐)"、"MAY(可以)"和"OPTIONAL(可选)"应按 [RFC2119] 中的描述进行解释。

形式化语法由 [RFC5234] 定义,包括 [RFC5234] 附录 B 中定义的核心规则。

以"C:" 开头的示例行由客户端发送,以"S:" 开头的由服务器发送。如果单个"C:" 或"S:" 标签适用于多行,那么这些行之间的换行仅为编辑清晰起见,并不属于实际的协议交换。

2.1. 术语

本文档使用了 [RFC4949](《互联网安全术语表》)中定义的若干术语,包括:认证(authentication)、认证交换(authentication exchange)、认证信息(authentication information)、暴力破解(brute force)、质询-响应(challenge-response)、密码学哈希函数(cryptographic hash function)、字典攻击(dictionary attack)、窃听(eavesdropping)、哈希结果(hash result)、带密钥的哈希(keyed hash)、中间人(man-in-the-middle)、现时值(nonce)、单向加密函数(one-way encryption function)、口令(password)、重放攻击(replay attack)与盐(salt)。不熟悉这些术语的读者应将该术语表作为参考。

以下给出一些澄清与补充定义:

2.2. 记法

算法的伪代码描述使用以下记法:

Hi() 本质上就是 PBKDF2 [RFC2898],其中 HMAC() 作为伪随机函数(PRF),且 dkLen == HMAC() 的输出长度 == H() 的输出长度。

3. SCRAM 算法概述

下面描述一次完整的、未压缩的 SASL SCRAM 认证交换。SCRAM 并不禁止以下任一做法:将客户端首条消息与应用协议定义的 SASL 认证请求("initial client response")一起发送,或将服务器最终消息作为应用协议定义的认证交换 SASL 结果中的附加数据发送。更多细节见 [RFC4422]。

注意本节省略了一些细节,例如客户端与服务器的现时值(nonce)。更多细节见第 5 节。

首先,SCRAM 客户端持有用户名与口令(*)(或 ClientKey/ServerKey,或 SaltedPassword)。它将用户名发送给服务器,服务器据此检索相应的认证信息,即盐、StoredKey、ServerKey 以及迭代数 i。(注意,服务器实现可以选择对所有账户使用相同的迭代数。)服务器将盐与迭代数发送给客户端,客户端随后计算以下各值,并向服务器发送一个 ClientProof:

(*)注意用户名与口令都必须以 UTF-8 [RFC3629] 编码。

说明性注记:鼓励实现者创建同时使用了含非 ASCII 码位的用户名与口令的测试用例。特别地,测试那些"Unicode 标准规范化形式 C(Normalization Form C)"与"Unicode 标准规范化形式 KC(Normalization Form KC)"互不相同的码点是很有用的。此类码点的例子包括 Vulgar Fraction One Half(U+00BD)与 Acute Accent(U+00B4)。

   SaltedPassword  := Hi(Normalize(password), salt, i)
   ClientKey       := HMAC(SaltedPassword, "Client Key")
   StoredKey       := H(ClientKey)
   AuthMessage     := client-first-message-bare + "," +
                      server-first-message + "," +
                      client-final-message-without-proof
   ClientSignature := HMAC(StoredKey, AuthMessage)
   ClientProof     := ClientKey XOR ClientSignature
   ServerKey       := HMAC(SaltedPassword, "Server Key")
   ServerSignature := HMAC(ServerKey, AuthMessage)

服务器通过计算 ClientSignature、将其与 ClientProof 进行异或运算来恢复 ClientKey,并对 ClientKey 应用哈希函数、将结果与 StoredKey 比较,从而认证客户端。如果 ClientKey 正确,就证明客户端能够访问该用户的口令。

类似地,客户端通过计算 ServerSignature 并将其与服务器发送的值进行比较来认证服务器。若两者相等,则证明服务器能够访问该用户的 ServerKey。

AuthMessage 通过拼接认证交换中的各条消息计算得到。这些消息的格式在第 7 节定义。

4. SCRAM 机制名称

SCRAM 机制名称是一个字符串"SCRAM-",后接取自 IANA"Hash Function Textual Names"注册表(见 http://www.iana.org)的底层哈希函数名的大写形式,并可选择后接后缀"-PLUS"(见下文)。注意 SASL 机制名称限制为 20 个八位组,这意味着只能使用长度不超过 9 个八位组(20 - length("SCRAM-") - length("-PLUS"))的哈希函数名。对于底层哈希函数名长于 9 个八位组的情况,只要不与 IANA"Hash Function Textual Names"注册表中的任何其他哈希函数名冲突,就可以使用一个替代的 9 八位组(或更短)名称来构造相应的 SCRAM 机制名称。为防止将来冲突,此类替代名称应在 IANA"Hash Function Textual Names"注册表中注册。

为互操作性,所有 SCRAM 客户端与服务器都必须实现 SCRAM-SHA-1 认证机制,即使用 [RFC3174] 所定义的 SHA-1 哈希函数的 SCRAM 系列认证机制。

"-PLUS"后缀仅在服务器支持对外部信道进行信道绑定时使用。如果服务器支持信道绑定,它将通告它所支持的任意机制(例如 SCRAM-SHA-1)的"裸(bare)"版本与"加(plus)"版本(即同时通告 SCRAM-SHA-1 与 SCRAM-SHA-1-PLUS)。如果服务器不支持信道绑定,则它只通告该机制的"裸"版本(例如仅 SCRAM-SHA-1)。"-PLUS"的存在是为了允许协商是否使用信道绑定。见第 6 节。

5. SCRAM 认证交换

SCRAM 是一种 SASL 机制,其客户端应答与服务器质询消息是基于文本的、包含一个或多个由逗号分隔的属性-值对的消息。每个属性有一个单字母名称。这些消息及其属性在第 5.1 节描述,并在第 7 节定义。

SCRAM 是一种客户端首发的(client-first)SASL 机制(见 [RFC4422] 第 5 节第 2a 项),并在服务器指示成功结果时一并返回附加数据。

下面是当客户端不支持信道绑定时的一次简单 SCRAM-SHA-1 认证交换示例(使用的用户名是"user",口令是"pencil"):

   C: n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL
   S: r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,
      i=4096
   C: c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,
      p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=
   S: v=rmF9pqV8S7suAoZWja4dJRkFsKQ=

首先,客户端发送包含以下内容的"client-first-message(客户端首条消息)":

注意,客户端的首条消息总是以"n"、"y"或"p"开头;否则该消息无效,认证必须失败。这很重要,因为它为 GS2 的扩展性(例如增加安全层支持)留出了空间。

作为响应,服务器发送"server-first-message(服务器首条消息)",其中包含用户的迭代数 i 与用户的盐,并将其自身的现时值附加到客户端指定的现时值之后。

随后客户端发送"client-final-message(客户端最终消息)"作为应答,其中包含相同的现时值以及一个使用所选哈希函数、按前述方式计算的 ClientProof。

服务器验证现时值与证明(proof),验证授权标识(若客户端在首条消息中提供)被授权以认证标识的身份行事,最后以一个"server-final-message(服务器最终消息)"作为应答,结束认证交换。

此后,客户端通过计算 ServerSignature 并将其与服务器发送的值进行比较来认证服务器。若两者不同,客户端必须认为认证交换未成功,并可能须要断开连接。

5.1. SCRAM 属性

本节描述允许使用的属性、它们的用途以及其值的格式。所有属性名均为单个 US-ASCII 字母,且区分大小写。

注意,客户端或服务器消息中属性的顺序是固定的,但扩展属性(由"extensions"这个 ABNF 产生式描述)除外,它可以按任意顺序出现在指定位置。权威参考见第 7 节。

5.2. 与 SASL 机制要求的符合性

本节描述与 [RFC4422] 第 5 节规定的 SASL 机制要求的符合性。

  1. "SCRAM-SHA-1"与"SCRAM-SHA-1-PLUS"。
  2. 2a)SCRAM 是一种客户端首发的机制。
  3. 2b)SCRAM 在成功时发送附加数据。
  4. SCRAM 能够将授权标识从客户端传送到服务器。
  5. SCRAM 不提供任何安全层(SCRAM 以信道绑定替代之)。
  6. SCRAM 具有保护授权标识的哈希。

6. 信道绑定

SCRAM 支持对外部安全信道(如 TLS)的信道绑定。客户端与服务器可能支持也可能不支持信道绑定,因此信道绑定的使用是可协商的。然而,SCRAM 不提供安全层,因此 SCRAM 必须为信道绑定的协商提供完整性保护。

信道绑定的使用按如下方式协商:

服务器必须始终验证客户端的"c="字段。服务器通过构造"c="属性的值,然后检查它是否与客户端的 c= 属性值匹配来做到这一点。

关于信道绑定的更多讨论,以及各种安全协议信道绑定数据的语法,见 [RFC5056]。

6.1. 默认信道绑定

对于未自行提供信道绑定类型协商的所有 SASL 应用协议,提供如下默认信道绑定类型协商过程。

"tls-unique"是任何未指定信道绑定类型的应用的默认信道绑定类型。

如果服务器实现了任何信道绑定,则必须实现"tls-unique" [RFC5929] 信道绑定类型。如果客户端实现了任何信道绑定,则应该实现"tls-unique" [RFC5929] 信道绑定类型。客户端与服务器应选择最高层/最内层端到端的 TLS 信道作为要绑定的信道。

服务器必须选择客户端所指明的信道绑定类型,若不支持则使认证失败。

7. 形式化语法

下列语法规范使用 [RFC5234] 规定的增广巴科斯-瑙尔范式(ABNF)记法。"UTF8-2"、"UTF8-3"与"UTF8-4"这些非终结符定义于 [RFC3629]。

   ALPHA = <as defined in RFC 5234 appendix B.1>
   DIGIT = <as defined in RFC 5234 appendix B.1>
   UTF8-2 = <as defined in RFC 3629 (STD 63)>
   UTF8-3 = <as defined in RFC 3629 (STD 63)>
   UTF8-4 = <as defined in RFC 3629 (STD 63)>

   attr-val        = ALPHA "=" value
                     ;; Generic syntax of any attribute sent
                     ;; by server or client

   value           = 1*value-char

   value-safe-char = %x01-2B / %x2D-3C / %x3E-7F /
                     UTF8-2 / UTF8-3 / UTF8-4
                     ;; UTF8-char except NUL, "=", and ",".

   value-char      = value-safe-char / "="

   printable       = %x21-2B / %x2D-7E
                     ;; Printable ASCII except ",".
                     ;; Note that any "printable" is also
                     ;; a valid "value".

   base64-char     = ALPHA / DIGIT / "/" / "+"

   base64-4        = 4base64-char

   base64-3        = 3base64-char "="

   base64-2        = 2base64-char "=="

   base64          = *base64-4 [base64-3 / base64-2]

   posit-number = %x31-39 *DIGIT
                     ;; A positive number.

   saslname        = 1*(value-safe-char / "=2C" / "=3D")
                     ;; Conforms to <value>.

   authzid         = "a=" saslname
                     ;; Protocol specific.

   cb-name         = 1*(ALPHA / DIGIT / "." / "-")
                      ;; See RFC 5056, Section 7.
                      ;; E.g., "tls-server-end-point" or
                      ;; "tls-unique".

   gs2-cbind-flag  = ("p=" cb-name) / "n" / "y"
                     ;; "n" -> client doesn't support channel binding.
                     ;; "y" -> client does support channel binding
                     ;;        but thinks the server does not.
                     ;; "p" -> client requires channel binding.
                     ;; The selected channel binding follows "p=".

   gs2-header      = gs2-cbind-flag "," [ authzid ] ","
                     ;; GS2 header for SCRAM
                     ;; (the actual GS2 header includes an optional
                     ;; flag to indicate that the GSS mechanism is not
                     ;; "standard", but since SCRAM is "standard", we
                     ;; don't include that flag).

   username        = "n=" saslname
                     ;; Usernames are prepared using SASLprep.

   reserved-mext  = "m=" 1*(value-char)
                     ;; Reserved for signaling mandatory extensions.
                     ;; The exact syntax will be defined in
                     ;; the future.

   channel-binding = "c=" base64
                     ;; base64 encoding of cbind-input.

   proof           = "p=" base64

   nonce           = "r=" c-nonce [s-nonce]
                     ;; Second part provided by server.

   c-nonce         = printable

   s-nonce         = printable

   salt            = "s=" base64

   verifier        = "v=" base64
                     ;; base-64 encoded ServerSignature.

   iteration-count = "i=" posit-number
                     ;; A positive number.

   client-first-message-bare =
                     [reserved-mext ","]
                     username "," nonce ["," extensions]

   client-first-message =
                     gs2-header client-first-message-bare

   server-first-message =
                     [reserved-mext ","] nonce "," salt ","
                     iteration-count ["," extensions]

   client-final-message-without-proof =
                     channel-binding "," nonce [","
                     extensions]

   client-final-message =
                     client-final-message-without-proof "," proof

   server-error = "e=" server-error-value

   server-error-value = "invalid-encoding" /
                  "extensions-not-supported" /  ; unrecognized 'm' value
                  "invalid-proof" /
                  "channel-bindings-dont-match" /
                  "server-does-support-channel-binding" /
                    ; server does not support channel binding
                  "channel-binding-not-supported" /
                  "unsupported-channel-binding-type" /
                  "unknown-user" /
                  "invalid-username-encoding" /
                    ; invalid username encoding (invalid UTF-8 or
                    ; SASLprep failed)
                  "no-resources" /
                  "other-error" /
                  server-error-value-ext
           ; Unrecognized errors should be treated as "other-error".
           ; In order to prevent information disclosure, the server
           ; may substitute the real reason with "other-error".

   server-error-value-ext = value
           ; Additional error reasons added by extensions
           ; to this document.

   server-final-message = (server-error / verifier)
                     ["," extensions]

   extensions = attr-val *("," attr-val)
                     ;; All extensions are optional,
                     ;; i.e., unrecognized attributes
                     ;; not defined in this document
                     ;; MUST be ignored.

   cbind-data    = 1*OCTET

   cbind-input   = gs2-header [ cbind-data ]
                     ;; cbind-data MUST be present for
                     ;; gs2-cbind-flag of "p" and MUST be absent
                     ;; for "y" or "n".

8. SCRAM 作为 GSS-API 机制

本节及其子节、以及本文档其他位置未引用的本节所有规范性参考,对于 SASL 实现者而言是资料性(INFORMATIONAL)的,但对于 GSS-API 实现者而言是规范性(NORMATIVE)的。

SCRAM 实际上也是一种 GSS-API 机制。消息是相同的,但(a)当 SCRAM 作为 GSS-API 机制使用时,客户端首条消息上的 GS2 头与信道绑定数据被排除在外,且(b)RFC2743 第 3.1 节的初始上下文令牌头被前缀到客户端的首条认证消息(上下文令牌)之前。

用于 SCRAM-SHA-1 的 GSS-API 机制 OID 为 1.3.6.1.5.5.14(见第 10 节)。

SCRAM 安全上下文的 mutual_state 标志(GSS_C_MUTUAL_FLAG)总是被置为 TRUE。SCRAM 不支持凭据委派(credential delegation),因此 SCRAM 安全上下文的 deleg_state 标志(GSS_C_DELEG_FLAG)总是被置为 FALSE。

8.1. 适用于 SCRAM 的 GSS-API 主体名称类型

SCRAM 并不显式命名接受方(acceptor)主体。然而,使用接受方主体名称来查找或提示输入口令是有用的。因此,SCRAM 支持标准的通用名称语法用于接受方,例如 GSS_C_NT_HOSTBASED_SERVICE(见 [RFC2743] 第 4.1 节)。实现应使用传入 GSS_Init_sec_context() 的目标名称(如果有的话)来帮助检索或提示输入 SCRAM 口令。

SCRAM 仅支持发起方(initiator)的单一名称类型:GSS_C_NT_USER_NAME。GSS_C_NT_USER_NAME 是 SCRAM 的默认名称类型。

除第 5.1 节描述的 SASLprep 应用之外,SCRAM 没有名称规范化过程。

SCRAM 主体名称的查询、显示与导出名称语法都是相同的。没有 SCRAM 特定的名称语法(SCRAM 发起方主体名称是自由格式);应用应使用通用的 GSS-API 名称类型,如 GSS_C_NT_USER_NAME 与 GSS_C_NT_HOSTBASED_SERVICE(见 [RFC2743] 第 4 节)。当然,导出的名称令牌符合 [RFC2743] 第 3.2 节,但令牌的"NAME"部分只是一个 SCRAM 用户名。

8.2. 适用于 SCRAM 的 GSS-API 逐消息令牌

作为 GSS-API 机制的 SCRAM 的逐消息令牌,应与 Kerberos V 的 GSS-API 机制 [RFC4121] 的逐消息令牌相同(见第 4.2 节及其子节),使用 Kerberos V 的"aes128-cts-hmac-sha1-96"加密类型 [RFC3962]。

replay_det_state(GSS_C_REPLAY_FLAG)、sequence_state(GSS_C_SEQUENCE_FLAG)、conf_avail(GSS_C_CONF_FLAG)与 integ_avail(GSS_C_CONF_FLAG)这些安全上下文标志总是被置为 TRUE。

128 位的会话"协议密钥(protocol key)"应通过使用 HMAC(StoredKey, "GSS-API session key" || ClientKey || AuthMessage) 最不显著(最右侧)的 128 位来派生。"特定密钥(specific keys)"随后按 [RFC4121]、[RFC3961] 与 [RFC3962] 第 2 节的通常方式派生。

"protocol key"与"specific key"是 Kerberos V5 的术语 [RFC3961]。

SCRAM 支持 PROT_READY,并且在发起方一侧,于收到服务器对初始安全上下文令牌的应答时首先进入 PROT_READY 状态。

8.3. 适用于 SCRAM 的 GSS_Pseudo_random()

SCRAM 的 GSS_Pseudo_random() [RFC4401] 应与 Kerberos V 的 GSS-API 机制 [RFC4402] 相同。SCRAM 没有接受方断言的子会话密钥,因此对于 SCRAM 的 GSS_Pseudo_random() 而言,GSS_C_PRF_KEY_FULL 与 GSS_C_PRF_KEY_PARTIAL 是等价的。用于 GSS_Pseudo_random() 的协议密钥应与第 8.2 节定义的密钥相同。

9. 安全考量

如果认证交换是在没有强安全层(如具有数据保密性的 TLS)的情况下进行的,那么被动窃听者可以获得足够信息,发起离线的字典攻击或暴力破解攻击,从而恢复用户的口令。该攻击所需的时间取决于所选的密码学哈希函数、口令的强度以及服务器提供的迭代数。具有强加密的外部安全层将阻止此类攻击。

如果用于保护 SCRAM 交换的外部安全层使用了匿名密钥交换,那么 SCRAM 信道绑定机制可用于检测对安全层的中间人攻击,并由此导致认证失败。然而,中间人攻击者已经获得足够信息来发起离线字典攻击或暴力破解攻击。为此,SCRAM 允许随着时间推移提高迭代数。(注意,仅持有"StoredKey"和"ServerKey"的服务器无法在成功认证后自动提高迭代数。这种提高需要重置用户的口令。)

如果认证信息从认证数据库中被盗,那么可以发起离线字典攻击或暴力破解攻击来恢复用户的口令。盐的使用在一定程度上缓解了此攻击,因为它要求对每个口令分别发起攻击。能够抵御此类攻击的认证机制是存在的(例如 EKE 类机制)。RFC 2945 [RFC2945] 就是此类技术的一个例子。工作组选择不以 EKE 类机制作为 SCRAM 的基础。

如果攻击者从认证信息库中获取了认证信息,并窃听某次认证交换或冒充服务器,该攻击者就获得了冒充该用户去对付所有使用相同哈希函数、口令、迭代数与盐、提供 SCRAM 访问的服务器的能力。因此,使用随机生成的盐值十分重要。

SCRAM 不协商要使用的哈希函数。哈希函数的协商留给 SASL 机制协商处理。重要的是,客户端必须能够对本地可用的机制列表按偏好排序,以便客户端可以从服务器通告的机制列表中挑选合适的机制使用。此偏好顺序此处未做规定,因为它属于本地事务。偏好顺序应同时包含机制密码学强度的客观与主观评判(例如,使用 SHA-1 后继者的 SCRAM 可能优先于使用 SHA-1 的 SCRAM)。

注意,为保护 SASL 机制协商,应用通常必须两次列出服务器机制:一次在认证之前,一次在认证之后(后者使用安全层)。由于 SCRAM 不提供安全层,保护机制协商的唯一方式是(a)对外部信道使用信道绑定,或(b)使用对用户提供服务器名进行认证的外部信道。

SCRAM 不抵御信道绑定类型的降级攻击。协商信道绑定类型、以及在该协商中处理降级攻击的复杂性,被有意排除在本文档范围之外。

恶意服务器可以通过发送很大的迭代数值,对客户端发起计算性的拒绝服务攻击。

关于生成随机性的更多信息,见 [RFC4086]。

10. IANA 考量

IANA 已将从 [RFC4422] 建立的 SASL 机制注册表中新增的下列 SASL 机制系列加入:

   To: iana@iana.org
   Subject: Registration of a new SASL family SCRAM

   SASL mechanism name (or prefix for the family): SCRAM-*
   Security considerations: Section 7 of [RFC5802]
   Published specification (optional, recommended): [RFC5802]
   Person & email address to contact for further information:
   IETF SASL WG <sasl@ietf.org>
   Intended usage: COMMON
   Owner/Change controller: IESG <iesg@ietf.org>
   Note: Members of this family MUST be explicitly registered
   using the "IETF Review" [RFC5226] registration procedure.
   Reviews MUST be requested on the SASL mailing list
   <sasl@ietf.org> (or a successor designated by the responsible
   Security AD).

给未来的 SCRAM 机制设计者的提示:每个新的 SCRAM-SASL 机制必须显式在 IANA 注册,并且必须符合本文档第 4 节定义的 SCRAM 机制命名约定。

IANA 已从 [RFC4422] 建立的 SASL 机制注册表中新增下列条目:

   To: iana@iana.org
   Subject: Registration of a new SASL mechanism SCRAM-SHA-1

   SASL mechanism name (or prefix for the family): SCRAM-SHA-1
   Security considerations: Section 7 of [RFC5802]
   Published specification (optional, recommended): [RFC5802]
   Person & email address to contact for further information:
   IETF SASL WG <sasl@ietf.org>
   Intended usage: COMMON
   Owner/Change controller: IESG <iesg@ietf.org>
   Note:
   To: iana@iana.org
   Subject: Registration of a new SASL mechanism SCRAM-SHA-1-PLUS

   SASL mechanism name (or prefix for the family): SCRAM-SHA-1-PLUS
   Security considerations: Section 7 of [RFC5802]
   Published specification (optional, recommended): [RFC5802]
   Person & email address to contact for further information:
   IETF SASL WG <sasl@ietf.org>
   Intended usage: COMMON
   Owner/Change controller: IESG <iesg@ietf.org>
   Note:

根据本文档,IANA 已从 iso.org.dod.internet.security.mechanisms 前缀(见"SMI Security for Mechanism Codes"注册表)中为 SCRAM-SHA-1 分配了一个 GSS-API 机制 OID。

11. 致谢

本文档得益于 SASL 工作组邮件列表上的讨论。作者特别感谢 Dave Cridland、Simon Josefsson、Jeffrey Hutzelman、Kurt Zeilenga、Pasi Eronen、Ben Campbell、Peter Saint-Andre 与 Tobias Markmann 对本文档的贡献。特别感谢 Simon Josefsson 对本文档的引导,以及完成了本规范最早的若干实现之一。

12. 参考文献

12.1. 规范性参考文献

12.2. 面向 GSS-API 实现者的规范性参考文献

12.3. 资料性参考文献

附录 A. 其他认证机制

DIGEST-MD5 [DIGESTHISTORIC] 机制已被证明过于复杂而难以实现与测试,因此互操作性很差。其安全层常常未实现,且几乎从不使用;每个人都改用 TLS。关于导致创建 SCRAM 的、DIGEST-MD5 的更完整问题列表,见 [DIGESTHISTORIC]。

CRAM-MD5 这一 SASL 机制虽被广泛部署,但也存在一些问题。特别是,它缺少一些现代 SASL 特性,例如对国际化用户名与口令的支持、对传递授权标识的支持,以及对信道绑定的支持。它也不支持服务器认证。关于 CRAM-MD5 更完整的问题列表,见 [CRAMHISTORIC]。

PLAIN [RFC4616] 这一 SASL 机制允许恶意服务器或窃听者冒充认证用户去对付该用户拥有相同口令的任何其他服务器。除非使用 TLS,否则它还在网络上以明文发送口令。它不支持服务器认证。

附录 B. 设计动机

以下设计目标塑造了本文档。注意,其中一些目标自文档初始版本以来已经改变。

作者地址

Chris Newman
Oracle
800 Royal Oaks
Monrovia, CA 91016
USA
EMail: chris.newman@oracle.com

Abhijit Menon-Sen
Oryx Mail Systems GmbH
EMail: ams@toroid.org

Alexey Melnikov
Isode, Ltd.
EMail: Alexey.Melnikov@isode.com

Nicolas Williams
Oracle
5300 Riata Trace Ct
Austin, TX 78727
USA
EMail: Nicolas.Williams@oracle.com