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

RFC 4616:PLAIN SASL 机制

封面

项目内容
文档标题The PLAIN Simple Authentication and Security Layer (SASL) Mechanism(PLAIN 简单认证与安全层(SASL)机制)
RFC 编号4616
作者 / 编辑K. Zeilenga(主编),OpenLDAP Foundation
发布日期2006 年 8 月
类别Standards Track(标准跟踪)
更新关系取代 RFC 2595 的第 6 节
译本说明本页为非官方中文译本,权威性以英文原文为准

摘要

本文档定义了一种简单的明文用户名/口令简单认证与安全层(SASL)机制,称为 PLAIN 机制。PLAIN 机制意在那些缺少简单口令认证命令的协议中,与下层提供的数据保密服务结合使用。

本备忘录的状态

本备忘录为互联网社区规定了一种互联网标准跟踪协议,并请各方提出讨论与改进建议。有关本协议的规范化状态与现状,请参考"互联网官方协议标准"(STD 1)的当前版本。本备忘录的分发不受限制。

Copyright (C) The Internet Society (2006).

目录

1. 引言

明文、可多次使用的口令简单、能与几乎所有现有的操作系统认证数据库互通,并且有助于平滑地过渡到更安全的基于口令的认证机制。其缺点在于,在数据保密性无法得到保障的网络连接上使用它们是不可接受的。

本文档定义了 PLAIN 简单认证与安全层([SASL])机制,用于那些没有明文登录命令的协议(例如 [ACAP] 或 [SMTP-AUTH])。本文档更新 RFC 2595,取代其第 6 节。相对 RFC 2595 的变更详见附录 A。

与该机制关联的名称为 "PLAIN"。

PLAIN SASL 机制不提供安全层。

在缺乏充分数据安全防护的情况下,不应使用 PLAIN 机制,因为该机制本身不提供完整性或保密性保护。该机制意在与应用层协议提供的数据安全保护(通常通过其使用传输层安全([TLS])服务)结合使用。

默认情况下,实现仅在已具备充分数据安全服务时才应通告并使用 PLAIN 机制。对于指明本机制为适用认证机制的 IETF 协议规范,必须要求实现支持一种强数据安全服务,例如 TLS。

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

2. PLAIN SASL 机制

该机制由一条从客户端发往服务器的消息构成,该消息是一串经 [UTF-8] 编码的 [Unicode] 字符。客户端先给出授权标识(以其行事的身份),后跟一个 NUL(U+0000)字符,再后是认证标识(其口令将被使用的身份),后跟一个 NUL(U+0000)字符,最后是明文口令。与其他 SASL 机制一样,当客户端希望服务器从凭据中推导出一个身份并以其作为授权标识时,客户端不提供授权标识。

使用增广 BNF([ABNF])描述的客户端消息的形式化语法如下。

message   = [authzid] UTF8NUL authcid UTF8NUL passwd
authcid   = 1*SAFE ; MUST accept up to 255 octets
authzid   = 1*SAFE ; MUST accept up to 255 octets
passwd    = 1*SAFE ; MUST accept up to 255 octets
UTF8NUL   = %x00 ; UTF-8 encoded NUL character

SAFE      = UTF1 / UTF2 / UTF3 / UTF4
             ;; any UTF-8 encoded Unicode character except NUL

UTF1      = %x01-7F ;; except NUL
UTF2      = %xC2-DF UTF0
UTF3      = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
           %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
UTF4      = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
           %xF4 %x80-8F 2(UTF0)
UTF0      = %x80-BF

授权标识(authzid)、认证标识(authcid)、口令(passwd)以及作为分隔符的 NUL 字符,都应作为 [UTF-8] 编码的 [Unicode] 字符串进行传输。由于 NUL(U+0000)字符被用作分隔符,NUL(U+0000)字符不得出现在 authzid、authcid 或 passwd 的产生式中。

authzid 产生式的形式取决于应用层协议的 SASL 概要 [SASL]。authcid 与 passwd 产生式则不受形式限制。不鼓励使用不可见字符或用户在某些键盘上可能无法输入的字符。

服务器必须能够接受长度最多为 255 八位组的 authzid、authcid 和 passwd 产生式。需注意,一个 Unicode 字符的 UTF-8 编码长度可能长达 4 个八位组。

收到消息后,服务器将用系统认证数据库核验消息中给出的认证标识(authcid)与口令(passwd),并核验该认证凭据是否允许客户端以(所给出或推导出的)授权标识(authzid)身份行事。若这两步都成功,则用户通过认证。

在用于核验过程之前,所给出的认证标识与口令字符串,以及数据库中的认证标识与口令字符串,都应经过准备。 [SASLPrep] 这一 [StringPrep] 算法的概要文件是推荐使用的准备算法。推荐使用 SASLprep 准备算法,以提高比较按预期方式行为的可能性。SASLprep 准备算法并非强制,以便允许服务器在适当时采用其他准备算法(包括不做准备)。例如,服务器为了与外部系统互通,可能需要使用不同的准备算法。

当使用 [SASLPrep] 准备所给出的字符串时,这些字符串应被视为"查询(query)"字符串([StringPrep] 第 7 节),因此未分配码点可以出现在其准备好的输出中。当使用 [SASLPrep] 准备数据库字符串时,这些字符串应被视为"存储(stored)"字符串([StringPrep] 第 7 节),因此未分配码点不得出现在其准备好的输出中。

无论使用何种准备算法,如果存储的是期望字符串的某个不可逆函数(例如散列)的输出,那么该字符串在输入该函数之前必须先经过准备。

无论使用何种准备算法,若准备失败或结果为空字符串,则核验必须失败。

当未提供授权标识时,服务器从所提供的认证标识字符串的准备后表示中推导出授权标识。这确保了认证标识的不同表示被推导时,会产生相同的授权标识。

服务器可以使用这些凭据来初始化任何新的认证数据库,例如适用于 [CRAM-MD5] 或 [DIGEST-MD5] 的数据库。

3. 伪代码

本节给出说明上述核验过程(使用散列口令与 SASLprep 准备函数)的伪代码。本节并非结论性规范。

boolean Verify(string authzid, string authcid, string passwd) {
  string pAuthcid = SASLprep(authcid, true); # prepare authcid
  string pPasswd = SASLprep(passwd, true);   # prepare passwd
  if (pAuthcid == NULL || pPasswd == NULL) {
    return false;     # preparation failed
  }
  if (pAuthcid == "" || pPasswd == "") {
    return false;     # empty prepared string
  }

  storedHash = FetchPasswordHash(pAuthcid);
  if (storedHash == NULL || storedHash == "") {
    return false;     # error or unknown authcid
  }

  if (!Compare(storedHash, Hash(pPasswd))) {
    return false;     # incorrect password
  }

  if (authzid == NULL ) {
    authzid = DeriveAuthzid(pAuthcid);
    if (authzid == NULL || authzid == "") {
        return false; # could not derive authzid
    }
  }

  if (!Authorize(pAuthcid, authzid)) {
    return false;     # not authorized
  }

  return true;
}

SASLprep 函数的第二个参数若为真,表示允许输入中出现未分配码点。当调用 SASLprep 函数为计算所存储的散列而准备口令时,第二个参数应为假。

传给 Authorize 函数的第二个参数并未由本代码进行准备。应查阅应用层 SASL 概要,以确定需要进行何种(若有的话)准备。

需注意,DeriveAuthzid 与 Authorize 函数(无论是实现为一个还是两个函数,无论其设计方式如何,也无论该机制实现能否在其他地方复用)的实现,都需要对机制以及应用层协议规范及/或实现细节具备了解与理解。

需注意,Authorize 函数的结果显然取决于本地授权模型与策略的细节。这两个函数也可能依赖于其他因素。

4. 示例

本节给出 PLAIN 认证交互的示例。这些示例旨在帮助读者理解上文内容。示例并非结论性规范。

"C:" 与 "S:" 分别表示客户端与服务器发出的行。"<NUL>" 表示单个 NUL(U+0000)字符。示例中使用应用配置访问协议([ACAP])。

第一个示例展示了 PLAIN 机制如何用于用户认证。

S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
C: a001 STARTTLS
S: a001 OK "Begin TLS negotiation now"
<TLS negotiation, further commands are under TLS layer>
S: * ACAP (SASL "CRAM-MD5" "PLAIN")
C: a002 AUTHENTICATE "PLAIN"
S: + ""
C: {21}
C: <NUL>tim<NUL>tanstaaftanstaaf
S: a002 OK "Authenticated"

第二个示例展示了 PLAIN 机制如何被用来试图冒用另一用户的身份。在本示例中,服务器拒绝了该请求。此外,本示例利用了协议可选的初始响应能力,以消除一次往返。

S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
C: a001 STARTTLS
S: a001 OK "Begin TLS negotiation now"
<TLS negotiation, further commands are under TLS layer>
S: * ACAP (SASL "CRAM-MD5" "PLAIN")
C: a002 AUTHENTICATE "PLAIN" {20+}
C: Ursel<NUL>Kurt<NUL>xipj3plmq
S: a002 NO "Not authorized to requested authorization identity"

5. 安全考量

由于 PLAIN 机制本身不提供完整性或保密性保护,在没有充分的外部数据安全保护(例如许多应用层协议所提供的 TLS 服务)时,不应使用它。默认情况下,除非已具备充分的数据安全服务,实现不应通告也不应使用 PLAIN 机制。

当使用 PLAIN 机制时,服务器便获得能力,得以使用同一口令冒充该用户访问所有服务,无论 TLS 或其他保密保护机制提供了何种加密。尽管许多其他认证机制也有类似弱点,但更强的 SASL 机制解决了这一问题。鼓励客户端提供一种运行模式,在其中所有可能将用户口令暴露给服务器的机制都被禁用。

[SASL] 的总体安全考量适用于本机制。

Unicode、[UTF-8] 与 [StringPrep] 的安全考量同样适用。

6. IANA 考量

IANA 已更新 SASL 机制注册表 [IANA-SASL] 中 PLAIN 机制的条目,以反映本文档现为其提供技术规范。

To: iana@iana.org
Subject: Updated Registration of SASL mechanism PLAIN

SASL mechanism name: PLAIN
Security considerations: See RFC 4616.
Published specification (optional, recommended): RFC 4616
Person & email address to contact for further information:
     Kurt Zeilenga <kurt@openldap.org>
     IETF SASL WG <ietf-sasl@imc.org>
Intended usage: COMMON
Author/Change controller: IESG <iesg@ietf.org>
Note: Updates existing entry for PLAIN

7. 致谢

本文档是 Chris Newman 所著 RFC 2595 的修订版。第 2 节中定义的语法部分借用了 Francois Yergeau 的 [UTF-8]。

本文档是 IETF 简单认证与安全层(SASL)工作组的工作成果。

8. 规范性参考文献

[ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, October 2005.

[Keywords] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[SASL] Melnikov, A., Ed., and K. Zeilenga, Ed., "Simple Authentication and Security Layer (SASL)", RFC 4422, June 2006.

[SASLPrep] Zeilenga, K., "SASLprep: Stringprep Profile for User Names and Passwords", RFC 4013, February 2005.

[StringPrep] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002.

[Unicode] The Unicode Consortium, "The Unicode Standard, Version 3.2.0" is defined by "The Unicode Standard, Version 3.0" (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), as amended by the "Unicode Standard Annex #27: Unicode 3.1" (http://www.unicode.org/reports/tr27/) and by the "Unicode Standard Annex #28: Unicode 3.2" (http://www.unicode.org/reports/tr28/).

[UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.

[TLS] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.1", RFC 4346, April 2006.

9. 资料性参考文献

[ACAP] Newman, C. and J. Myers, "ACAP -- Application Configuration Access Protocol", RFC 2244, November 1997.

[CRAM-MD5] Nerenberg, L., Ed., "The CRAM-MD5 SASL Mechanism", Work in Progress, June 2006.

[DIGEST-MD5] Melnikov, A., Ed., "Using Digest Authentication as a SASL Mechanism", Work in Progress, June 2006.

[IANA-SASL] IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL) MECHANISMS", <http://www.iana.org/assignments/sasl-mechanisms>.

[SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication", RFC 2554, March 1999.

附录 A. 自 RFC 2595 以来的变更

本附录不具规范性。

本文档取代 RFC 2595 的第 6 节。

本规范详述了服务器应如何将客户端提供的字符串与存储的字符串进行比较。

ABNF 语法已更新。具体而言,该语法现在允许在 authzid、authcid、passwd 产生式中使用换行(LINE FEED,U+000A)与回车(CARRIAGE RETURN,U+000D)字符。然而,这些控制字符能否被使用,取决于适用于该产生式的字符串准备规则。对于 passwd 与 authcid 产生式,控制字符被禁止。对于 authzid,则必须查阅应用层 SASL 概要。此变更使得 PLAIN 能够携带 SASL 中允许的所有可能的授权标识字符串。

增加了伪代码。

示例部分已扩充,以说明 PLAIN 机制的更多特性。

作者地址

Kurt D. Zeilenga
OpenLDAP Foundation

EMail: Kurt@OpenLDAP.org

Copyright (C) The Internet Society (2006).

本文档受 BCP 78 所含的权利、许可与限制约束,除其中另有规定外,作者保留其全部权利。

本文档及其中所包含的信息按"原样(AS IS)"提供,贡献者、其代表或(若有)赞助其的组织、互联网协会以及互联网工程任务组,否认一切明示或默示的担保,包括但不限于任何关于使用本文档信息不会侵犯任何权利的担保,以及任何关于适销性或特定用途适用性的默示担保。

知识产权

IETF 对于可能被主张为涉及本文档所描述技术的实现或使用、或关于任何此类权利下的许可是否可得及其范围的任何知识产权或其他权利的有效性或范围,不持任何立场;IETF 也不表示其已作出独立努力来识别任何此类权利。有关 RFC 文档中权利相关程序的信息,可在 BCP 78 与 BCP 79 中找到。

向 IETF 秘书处提交的知识产权披露副本、任何关于将提供许可的保证,或本规范实现者或使用者为获得使用此类专有权利的通用许可或授权而尝试的结果,可从 IETF 在线知识产权仓库 http://www.ietf.org/ipr 获取。

IETF 邀请任何相关方就其注意到的、可能覆盖实现本标准所需技术的任何版权、专利或专利申请,或其他专有权利,提请 IETF 关注。请将相关信息寄至 ietf-ipr@ietf.org。

致谢(结尾)

RFC 编辑职能的资助由 IETF 行政支持活动(IASA)提供。