Network Working Group                                           P. Leach
Request for Comments: 2831                                     Microsoft
Category: Standards Track                                      C. Newman
                                                                Innosoft
                                                                May 2000
        
Network Working Group                                           P. Leach
Request for Comments: 2831                                     Microsoft
Category: Standards Track                                      C. Newman
                                                                Innosoft
                                                                May 2000
        

Using Digest Authentication as a SASL Mechanism

使用摘要身份验证作为SASL机制

Status of this Memo

本备忘录的状况

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

本文件规定了互联网社区的互联网标准跟踪协议,并要求进行讨论和提出改进建议。有关本协议的标准化状态和状态,请参考当前版本的“互联网官方协议标准”(STD 1)。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

Abstract

摘要

This specification defines how HTTP Digest Authentication [Digest] can be used as a SASL [RFC 2222] mechanism for any protocol that has a SASL profile. It is intended both as an improvement over CRAM-MD5 [RFC 2195] and as a convenient way to support a single authentication mechanism for web, mail, LDAP, and other protocols.

本规范定义了如何将HTTP摘要身份验证[Digest]用作任何具有SASL配置文件的协议的SASL[RFC 2222]机制。它是对CRAM-MD5[RFC 2195]的改进,也是支持web、邮件、LDAP和其他协议的单一身份验证机制的方便方法。

Table of Contents

目录

   1 INTRODUCTION.....................................................2
    1.1 CONVENTIONS AND NOTATION......................................2
    1.2 REQUIREMENTS..................................................3
   2 AUTHENTICATION...................................................3
    2.1 INITIAL AUTHENTICATION........................................3
     2.1.1 Step One...................................................3
     2.1.2 Step Two...................................................6
     2.1.3 Step Three................................................12
    2.2 SUBSEQUENT AUTHENTICATION....................................12
     2.2.1 Step one..................................................13
     2.2.2 Step Two..................................................13
    2.3 INTEGRITY PROTECTION.........................................13
    2.4 CONFIDENTIALITY PROTECTION...................................14
   3 SECURITY CONSIDERATIONS.........................................15
    3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........15
    3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................16
    3.3 REPLAY ATTACKS...............................................16
        
   1 INTRODUCTION.....................................................2
    1.1 CONVENTIONS AND NOTATION......................................2
    1.2 REQUIREMENTS..................................................3
   2 AUTHENTICATION...................................................3
    2.1 INITIAL AUTHENTICATION........................................3
     2.1.1 Step One...................................................3
     2.1.2 Step Two...................................................6
     2.1.3 Step Three................................................12
    2.2 SUBSEQUENT AUTHENTICATION....................................12
     2.2.1 Step one..................................................13
     2.2.2 Step Two..................................................13
    2.3 INTEGRITY PROTECTION.........................................13
    2.4 CONFIDENTIALITY PROTECTION...................................14
   3 SECURITY CONSIDERATIONS.........................................15
    3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........15
    3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................16
    3.3 REPLAY ATTACKS...............................................16
        
    3.4 ONLINE DICTIONARY ATTACKS....................................16
    3.5 OFFLINE DICTIONARY ATTACKS...................................16
    3.6 MAN IN THE MIDDLE............................................17
    3.7 CHOSEN PLAINTEXT ATTACKS.....................................17
    3.8 SPOOFING BY COUNTERFEIT SERVERS..............................17
    3.9 STORING PASSWORDS............................................17
    3.10 MULTIPLE REALMS.............................................18
    3.11 SUMMARY.....................................................18
   4 EXAMPLE.........................................................18
   5 REFERENCES......................................................20
   6 AUTHORS' ADDRESSES..............................................21
   7 ABNF............................................................21
    7.1 AUGMENTED BNF................................................21
    7.2 BASIC RULES..................................................23
   8 SAMPLE CODE.....................................................25
   9 FULL COPYRIGHT STATEMENT........................................27
        
    3.4 ONLINE DICTIONARY ATTACKS....................................16
    3.5 OFFLINE DICTIONARY ATTACKS...................................16
    3.6 MAN IN THE MIDDLE............................................17
    3.7 CHOSEN PLAINTEXT ATTACKS.....................................17
    3.8 SPOOFING BY COUNTERFEIT SERVERS..............................17
    3.9 STORING PASSWORDS............................................17
    3.10 MULTIPLE REALMS.............................................18
    3.11 SUMMARY.....................................................18
   4 EXAMPLE.........................................................18
   5 REFERENCES......................................................20
   6 AUTHORS' ADDRESSES..............................................21
   7 ABNF............................................................21
    7.1 AUGMENTED BNF................................................21
    7.2 BASIC RULES..................................................23
   8 SAMPLE CODE.....................................................25
   9 FULL COPYRIGHT STATEMENT........................................27
        

1 Introduction

1导言

This specification describes the use of HTTP Digest Access Authentication as a SASL mechanism. The authentication type associated with the Digest SASL mechanism is "DIGEST-MD5".

本规范描述了HTTP摘要访问身份验证作为SASL机制的使用。与摘要SASL机制关联的身份验证类型为“摘要MD5”。

This specification is intended to be upward compatible with the "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication specified in [Digest]. The only difference in the "md5-sess" algorithm is that some directives not needed in a SASL mechanism have had their values defaulted.

本规范旨在向上兼容[Digest]中指定的HTTP/1.1摘要访问身份验证的“md5 sess”算法。“md5 sess”算法的唯一区别在于,SASL机制中不需要的某些指令的值已被默认。

There is one new feature for use as a SASL mechanism: integrity protection on application protocol messages after an authentication exchange.

有一个新特性可用作SASL机制:身份验证交换后应用程序协议消息的完整性保护。

Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext attacks, and permits the use of third party authentication servers, mutual authentication, and optimized reauthentication if a client has recently authenticated to a server.

此外,与CRAM-MD5相比,DIGEST-MD5可防止选择的明文攻击,并允许使用第三方身份验证服务器、相互身份验证和优化的重新身份验证(如果客户端最近已通过服务器身份验证)。

1.1 Conventions and Notation
1.1 约定和符号

This specification uses the same ABNF notation and lexical conventions as HTTP/1.1 specification; see appendix A.

本规范使用与HTTP/1.1规范相同的ABNF符号和词汇约定;见附录A。

Let { a, b, ... } be the concatenation of the octet strings a, b, ...

设{a,b,…}为八位元串a,b。。。

Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.

设H(s)为八位元字符串s的16个八位元MD5散列[RFC 1321]。

Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string k, a colon and the string s.

设KD(k,s)为H({k,“:”,s}),即字符串k、冒号和字符串s的16个八位组散列。

Let HEX(n) be the representation of the 16 octet MD5 hash n as a string of 32 hex digits (with alphabetic characters always in lower case, since MD5 is case sensitive).

设十六进制(n)表示16个八位MD5散列n,作为32个十六进制数字的字符串(字母字符总是小写,因为MD5区分大小写)。

Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet string s using the octet string k as a key.

设HMAC(k,s)是使用八位元串k作为键的八位元串s的16个八位元HMAC-MD5[RFC 2104]。

The value of a quoted string constant as an octet string does not include any terminating null character.

作为八位字节字符串的带引号的字符串常量的值不包括任何终止的空字符。

1.2 Requirements
1.2 要求

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC 2119].

本文件中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC 2119[RFC 2119]中的说明进行解释。

An implementation is not compliant if it fails to satisfy one or more of the MUST level requirements for the protocols it implements. An implementation that satisfies all the MUST level and all the SHOULD level requirements for its protocols is said to be "unconditionally compliant"; one that satisfies all the MUST level requirements but not all the SHOULD level requirements for its protocols is said to be "conditionally compliant."

如果一个实现未能满足其实现的协议的一个或多个必须级别的要求,则该实现是不兼容的。满足其协议所有必须级别和应级别要求的实现称为“无条件兼容”;满足其协议的所有必须级别要求但并非所有应级别要求的协议称为“有条件兼容”

2 Authentication

2认证

The following sections describe how to use Digest as a SASL authentication mechanism.

以下各节介绍如何将摘要用作SASL身份验证机制。

2.1 Initial Authentication
2.1 初始身份验证

If the client has not recently authenticated to the server, then it must perform "initial authentication", as defined in this section. If it has recently authenticated, then a more efficient form is available, defined in the next section.

如果客户端最近没有向服务器进行身份验证,则必须执行本节中定义的“初始身份验证”。如果它最近进行了身份验证,则可以使用更有效的表单,将在下一节中定义。

2.1.1 Step One
2.1.1 第一步

The server starts by sending a challenge. The data encoded in the challenge contains a string formatted according to the rules for a "digest-challenge" defined as follows:

服务器通过发送质询开始。质询中编码的数据包含根据“摘要质询”规则格式化的字符串,定义如下:

digest-challenge = 1#( realm | nonce | qop-options | stale | maxbuf | charset algorithm | cipher-opts | auth-param )

摘要挑战=1(领域|非当前| qop选项|过时| maxbuf |字符集算法|密码选项|身份参数)

        realm             = "realm" "=" <"> realm-value <">
        realm-value       = qdstr-val
        nonce             = "nonce" "=" <"> nonce-value <">
        nonce-value       = qdstr-val
        qop-options       = "qop" "=" <"> qop-list <">
        qop-list          = 1#qop-value
        qop-value         = "auth" | "auth-int" | "auth-conf" |
                             token
        stale             = "stale" "=" "true"
        maxbuf            = "maxbuf" "=" maxbuf-value
        maxbuf-value      = 1*DIGIT
        charset           = "charset" "=" "utf-8"
        algorithm         = "algorithm" "=" "md5-sess"
        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
                            "rc4-56" | token
        auth-param        = token "=" ( token | quoted-string )
        
        realm             = "realm" "=" <"> realm-value <">
        realm-value       = qdstr-val
        nonce             = "nonce" "=" <"> nonce-value <">
        nonce-value       = qdstr-val
        qop-options       = "qop" "=" <"> qop-list <">
        qop-list          = 1#qop-value
        qop-value         = "auth" | "auth-int" | "auth-conf" |
                             token
        stale             = "stale" "=" "true"
        maxbuf            = "maxbuf" "=" maxbuf-value
        maxbuf-value      = 1*DIGIT
        charset           = "charset" "=" "utf-8"
        algorithm         = "algorithm" "=" "md5-sess"
        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
                            "rc4-56" | token
        auth-param        = token "=" ( token | quoted-string )
        

The meanings of the values of the directives used above are as follows:

上述指令值的含义如下:

realm Mechanistically, a string which can enable users to know which username and password to use, in case they might have different ones for different servers. Conceptually, it is the name of a collection of accounts that might include the user's account. This string should contain at least the name of the host performing the authentication and might additionally indicate the collection of users who might have access. An example might be "registered_users@gotham.news.example.com". This directive is optional; if not present, the client SHOULD solicit it from the user or be able to compute a default; a plausible default might be the realm supplied by the user when they logged in to the client system. Multiple realm directives are allowed, in which case the user or client must choose one as the realm for which to supply to username and password.

从机制上讲,一个字符串可以让用户知道使用哪个用户名和密码,以防不同的服务器可能有不同的用户名和密码。从概念上讲,它是可能包括用户帐户的帐户集合的名称。此字符串应至少包含执行身份验证的主机的名称,并可能另外指示可能具有访问权限的用户集合。例如,“注册”_users@gotham.news.example.com". 本指令是可选的;如果不存在,客户端应向用户请求,或者能够计算默认值;一个合理的默认值可能是用户登录到客户端系统时提供的领域。允许使用多个领域指令,在这种情况下,用户或客户端必须选择一个领域作为向用户名和密码提供的领域。

nonce A server-specified data string which MUST be different each time a digest-challenge is sent as part of initial authentication. It is recommended that this string be base64 or hexadecimal data. Note that since the string is passed as a quoted string, the double-quote character is not allowed unless escaped (see section 7.2). The contents of the nonce are implementation dependent. The

nonce服务器指定的数据字符串,每次作为初始身份验证的一部分发送摘要质询时,该字符串必须不同。建议此字符串为base64或十六进制数据。请注意,由于字符串是作为带引号的字符串传递的,因此除非进行转义,否则不允许使用双引号字符(请参见第7.2节)。nonce的内容取决于实现。这个

security of the implementation depends on a good choice. It is RECOMMENDED that it contain at least 64 bits of entropy. The nonce is opaque to the client. This directive is required and MUST appear exactly once; if not present, or if multiple instances are present, the client should abort the authentication exchange.

实现的安全性取决于一个好的选择。建议它至少包含64位熵。nonce对客户端是不透明的。本指令是必需的,且必须准确出现一次;如果不存在,或者存在多个实例,则客户端应中止身份验证交换。

qop-options A quoted string of one or more tokens indicating the "quality of protection" values supported by the server. The value "auth" indicates authentication; the value "auth-int" indicates authentication with integrity protection; the value "auth-conf" indicates authentication with integrity protection and encryption. This directive is optional; if not present it defaults to "auth". The client MUST ignore unrecognized options; if the client recognizes no option, it should abort the authentication exchange.

qop选项由一个或多个令牌组成的带引号的字符串,表示服务器支持的“保护质量”值。值“auth”表示身份验证;值“auth int”表示具有完整性保护的身份验证;值“auth conf”表示具有完整性保护和加密的身份验证。本指令是可选的;如果不存在,则默认为“auth”。客户必须忽略未识别的选项;如果客户端无法识别任何选项,则应中止身份验证交换。

stale The "stale" directive is not used in initial authentication. See the next section for its use in subsequent authentications. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

stale初始身份验证中不使用“stale”指令。有关其在后续身份验证中的使用,请参见下一节。本指令最多可出现一次;如果存在多个实例,客户端应中止身份验证交换。

maxbuf A number indicating the size of the largest buffer the server is able to receive when using "auth-int" or "auth-conf". If this directive is missing, the default value is 65536. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

maxbuf一个数字,指示使用“auth int”或“auth conf”时服务器能够接收的最大缓冲区的大小。如果缺少此指令,则默认值为65536。本指令最多可出现一次;如果存在多个实例,客户端应中止身份验证交换。

charset This directive, if present, specifies that the server supports UTF-8 encoding for the username and password. If not present, the username and password must be encoded in ISO 8859-1 (of which US-ASCII is a subset). The directive is needed for backwards compatibility with HTTP Digest, which only supports ISO 8859-1. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

charset此指令(如果存在)指定服务器支持用户名和密码的UTF-8编码。如果不存在,用户名和密码必须用ISO 8859-1编码(US-ASCII是其中的一个子集)。该指令需要与HTTP摘要向后兼容,后者仅支持ISO 8859-1。本指令最多可出现一次;如果存在多个实例,客户端应中止身份验证交换。

algorithm This directive is required for backwards compatibility with HTTP Digest., which supports other algorithms. . This directive is required and MUST appear exactly once; if not present, or if multiple instances are present, the client should abort the authentication exchange.

算法此指令是与支持其他算法的HTTP摘要向后兼容所必需的。本指令是必需的,且必须准确出现一次;如果不存在,或者存在多个实例,则客户端应中止身份验证交换。

cipher-opts A list of ciphers that the server supports. This directive must be present exactly once if "auth-conf" is offered in the "qop-options" directive, in which case the "3des" and "des" modes are mandatory-to-implement. The client MUST ignore unrecognized options; if the client recognizes no option, it should abort the authentication exchange.

cipher选择服务器支持的密码列表。如果“qop options”指令中提供了“auth conf”,则该指令必须仅出现一次,在这种情况下,必须执行“3des”和“des”模式。客户必须忽略未识别的选项;如果客户端无法识别任何选项,则应中止身份验证交换。

des the Data Encryption Standard (DES) cipher [FIPS] in cipher block chaining (CBC) mode with a 56 bit key.

des数据加密标准(des)密码[FIPS]在密码分组链接(CBC)模式下使用56位密钥。

3des the "triple DES" cipher in CBC mode with EDE with the same key for each E stage (aka "two keys mode") for a total key length of 112 bits.

3des在CBC模式下使用EDE的“三重DES”密码,每个E阶段使用相同的密钥(也称为“两个密钥模式”),密钥总长度为112位。

rc4, rc4-40, rc4-56 the RC4 cipher with a 128 bit, 40 bit, and 56 bit key, respectively.

rc4、rc4-40、rc4-56分别使用128位、40位和56位密钥的rc4密码。

auth-param This construct allows for future extensions; it may appear more than once. The client MUST ignore any unrecognized directives.

auth param此构造允许将来扩展;它可能不止出现一次。客户端必须忽略任何无法识别的指令。

For use as a SASL mechanism, note that the following changes are made to "digest-challenge" from HTTP: the following Digest options (called "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent, and MUST be ignored if received):

要用作SASL机制,请注意,对HTTP中的“摘要质询”进行了以下更改:以下摘要选项(在HTTP术语中称为“指令”)未使用(即,不得发送,如果收到则必须忽略):

opaque domain

不透明域

The size of a digest-challenge MUST be less than 2048 bytes.

摘要质询的大小必须小于2048字节。

2.1.2 Step Two
2.1.2 第二步

The client makes note of the "digest-challenge" and then responds with a string formatted and computed according to the rules for a "digest-response" defined as follows:

客户机记录“摘要质询”,然后使用根据“摘要响应”规则格式化和计算的字符串进行响应,该规则定义如下:

digest-response = 1#( username | realm | nonce | cnonce | nonce-count | qop | digest-uri | response | maxbuf | charset | cipher | authzid | auth-param )

摘要响应=1#(用户名| realm | nonce | cnon | nonce count | qop |摘要uri |响应| maxbuf | charset | cipher | authzid | auth param)

       username         = "username" "=" <"> username-value <">
       username-value   = qdstr-val
       cnonce           = "cnonce" "=" <"> cnonce-value <">
       cnonce-value     = qdstr-val
       nonce-count      = "nc" "=" nc-value
       nc-value         = 8LHEX
       qop              = "qop" "=" qop-value
       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
       serv-type        = 1*ALPHA
       host             = 1*( ALPHA | DIGIT | "-" | "." )
       serv-name        = host
       response         = "response" "=" response-value
       response-value   = 32LHEX
       LHEX             = "0" | "1" | "2" | "3" |
                          "4" | "5" | "6" | "7" |
                          "8" | "9" | "a" | "b" |
                          "c" | "d" | "e" | "f"
       cipher           = "cipher" "=" cipher-value
       authzid          = "authzid" "=" <"> authzid-value <">
       authzid-value    = qdstr-val
        
       username         = "username" "=" <"> username-value <">
       username-value   = qdstr-val
       cnonce           = "cnonce" "=" <"> cnonce-value <">
       cnonce-value     = qdstr-val
       nonce-count      = "nc" "=" nc-value
       nc-value         = 8LHEX
       qop              = "qop" "=" qop-value
       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
       serv-type        = 1*ALPHA
       host             = 1*( ALPHA | DIGIT | "-" | "." )
       serv-name        = host
       response         = "response" "=" response-value
       response-value   = 32LHEX
       LHEX             = "0" | "1" | "2" | "3" |
                          "4" | "5" | "6" | "7" |
                          "8" | "9" | "a" | "b" |
                          "c" | "d" | "e" | "f"
       cipher           = "cipher" "=" cipher-value
       authzid          = "authzid" "=" <"> authzid-value <">
       authzid-value    = qdstr-val
        

username The user's name in the specified realm, encoded according to the value of the "charset" directive. This directive is required and MUST be present exactly once; otherwise, authentication fails.

username指定领域中的用户名,根据“charset”指令的值进行编码。本指令是必需的,且必须准确呈现一次;否则,身份验证将失败。

realm The realm containing the user's account. This directive is required if the server provided any realms in the "digest-challenge", in which case it may appear exactly once and its value SHOULD be one of those realms. If the directive is missing, "realm-value" will set to the empty string when computing A1 (see below for details).

域包含用户帐户的域。如果服务器在“摘要质询”中提供了任何领域,则需要此指令,在这种情况下,它可能只出现一次,并且其值应该是这些领域之一。如果缺少该指令,“realm value”将在计算A1时设置为空字符串(有关详细信息,请参阅下文)。

nonce The server-specified data string received in the preceding digest-challenge. This directive is required and MUST be present exactly once; otherwise, authentication fails.

nonce在前面的摘要质询中接收到的服务器指定的数据字符串。本指令是必需的,且必须准确呈现一次;否则,身份验证将失败。

cnonce A client-specified data string which MUST be different each time a digest-response is sent as part of initial authentication. The cnonce-value is an opaque quoted string value provided by the client and used by both client and server to avoid chosen plaintext attacks, and to provide mutual authentication. The security of the implementation depends on a good choice. It is RECOMMENDED that it contain at least 64 bits of entropy. This directive is required and MUST be present exactly once; otherwise, authentication fails.

cnonce客户端指定的数据字符串,每次作为初始身份验证的一部分发送摘要响应时,该字符串必须不同。cnonce值是客户端提供的不透明带引号的字符串值,客户端和服务器都使用该值来避免选择的明文攻击,并提供相互身份验证。实现的安全性取决于一个好的选择。建议它至少包含64位熵。本指令是必需的,且必须准确呈现一次;否则,身份验证将失败。

nonce-count The nc-value is the hexadecimal count of the number of requests (including the current request) that the client has sent with the nonce value in this request. For example, in the first request sent in response to a given nonce value, the client sends "nc=00000001". The purpose of this directive is to allow the server to detect request replays by maintaining its own copy of this count - if the same nc-value is seen twice, then the request is a replay. See the description below of the construction of the response value. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

nonce count nc值是客户端使用此请求中的nonce值发送的请求数(包括当前请求)的十六进制计数。例如,在响应给定nonce值而发送的第一个请求中,客户端发送“nc=00000001”。此指令的目的是允许服务器通过维护自己的此计数副本来检测请求重播-如果相同的nc值出现两次,则该请求为重播。有关响应值的构造,请参见下面的说明。本指令最多可出现一次;如果存在多个实例,客户端应中止身份验证交换。

qop Indicates what "quality of protection" the client accepted. If present, it may appear exactly once and its value MUST be one of the alternatives in qop-options. If not present, it defaults to "auth". These values affect the computation of the response. Note that this is a single token, not a quoted list of alternatives.

qop表示客户接受的“保护质量”。如果存在,它可能只出现一次,并且其值必须是qop选项中的备选值之一。如果不存在,则默认为“auth”。这些值会影响响应的计算。请注意,这是一个单独的标记,而不是引用的备选方案列表。

serv-type Indicates the type of service, such as "www" for web service, "ftp" for FTP service, "smtp" for mail delivery service, etc. The service name as defined in the SASL profile for the protocol see section 4 of [RFC 2222], registered in the IANA registry of "service" elements for the GSSAPI host-based service name form [RFC 2078].

serv type表示服务类型,如“www”表示web服务,“ftp”表示ftp服务,“smtp”表示邮件传递服务等。协议的SASL配置文件中定义的服务名称见[RFC 2222]第4节,在GSSAPI基于主机的服务名称表[RFC 2078]的“服务”元素IANA注册表中注册。

host The DNS host name or IP address for the service requested. The DNS host name must be the fully-qualified canonical name of the host. The DNS host name is the preferred form; see notes on server processing of the digest-uri.

主机请求的服务的DNS主机名或IP地址。DNS主机名必须是主机的完全限定规范名。DNS主机名是首选形式;请参阅有关摘要uri的服务器处理的说明。

serv-name Indicates the name of the service if it is replicated. The service is considered to be replicated if the client's service-location process involves resolution using standard DNS lookup operations, and if these operations involve DNS records (such as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case, the initial name used by the client is the "serv-name", and the final name is the "host" component. For example, the incoming mail service for "example.com" may be replicated through the use of MX records stored in the DNS, one of which points at an SMTP server called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be "mail3.example.com". If the service is not replicated, or the serv-name is identical to the host, then the serv-name component MUST be omitted.

serv name表示复制的服务的名称。如果客户端的服务定位过程涉及使用标准DNS查找操作进行解析,并且这些操作涉及将一个DNS名称解析为一组其他DNS名称的DNS记录(如SRV或MX),则认为该服务已复制。在这种情况下,客户端使用的初始名称是“serv名称”,最终名称是“主机”组件。例如,“example.com”的传入邮件服务可以通过使用DNS中存储的MX记录进行复制,其中一个记录指向名为“mail3.example.com”的SMTP服务器;它的“服务名称”将是“example.com”,它的“主机”将是“mail3.example.com”。如果未复制服务,或者服务名称与主机相同,则必须省略服务名称组件。

digest-uri Indicates the principal name of the service with which the client wishes to connect, formed from the serv-type, host, and serv-name. For example, the FTP service on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from the example above would have a "digest-uri" value of "smtp/mail3.example.com/example.com".

摘要uri表示客户端希望连接的服务的主体名称,由服务类型、主机和服务名称组成。例如,“FTP.example.com”上的FTP服务的“摘要uri”值为“FTP/FTP.example.com”;上面示例中的SMTP服务器的“摘要uri”值为“SMTP/mail3.example.com/example.com”。

Servers SHOULD check that the supplied value is correct. This will detect accidental connection to the incorrect server. It is also so that clients will be trained to provide values that will work with implementations that use a shared back-end authentication service that can provide server authentication.

服务器应检查提供的值是否正确。这将检测到与错误服务器的意外连接。这也是为了让客户机接受培训,以提供与使用可提供服务器身份验证的共享后端身份验证服务的实现协同工作的值。

The serv-type component should match the service being offered. The host component should match one of the host names of the host on which the service is running, or it's IP address. Servers SHOULD NOT normally support the IP address form, because server authentication by IP address is not very useful; they should only do so if the DNS is unavailable or unreliable. The serv-name component should match one of the service's configured service names.

服务类型组件应与所提供的服务匹配。主机组件应与运行服务的主机的主机名之一或其IP地址匹配。服务器通常不应该支持IP地址形式,因为通过IP地址进行服务器身份验证不是很有用;只有当DNS不可用或不可靠时,他们才应该这样做。serv name组件应与服务的一个已配置服务名称匹配。

This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange.

本指令最多可出现一次;如果存在多个实例,客户端应中止身份验证交换。

Note: In the HTTP use of Digest authentication, the digest-uri is the URI (usually a URL) of the resource requested -- hence the name of the directive.

注意:在HTTP使用摘要身份验证时,摘要uri是请求的资源的uri(通常是URL)——因此是指令的名称。

response A string of 32 hex digits computed as defined below, which proves that the user knows a password. This directive is required and MUST be present exactly once; otherwise, authentication fails.

响应一个由32个十六进制数字组成的字符串,按以下定义计算,证明用户知道密码。本指令是必需的,且必须准确呈现一次;否则,身份验证将失败。

maxbuf A number indicating the size of the largest buffer the client is able to receive. If this directive is missing, the default value is 65536. This directive may appear at most once; if multiple instances are present, the server should abort the authentication exchange.

maxbuf一个数字,指示客户端能够接收的最大缓冲区的大小。如果缺少此指令,则默认值为65536。本指令最多可出现一次;如果存在多个实例,服务器应中止身份验证交换。

charset This directive, if present, specifies that the client has used UTF-8 encoding for the username and password. If not present, the username and password must be encoded in ISO 8859-1 (of which US-ASCII is a subset). The client should send this directive only if the server has indicated it supports UTF-8. The directive is needed for backwards compatibility with HTTP Digest, which only supports ISO 8859-1.

charset此指令(如果存在)指定客户端已对用户名和密码使用UTF-8编码。如果不存在,用户名和密码必须用ISO 8859-1编码(US-ASCII是其中的一个子集)。仅当服务器指示它支持UTF-8时,客户端才应发送此指令。该指令需要与HTTP摘要向后兼容,后者仅支持ISO 8859-1。

LHEX 32 hex digits, where the alphabetic characters MUST be lower case, because MD5 is not case insensitive.

LHEX 32个十六进制数字,其中字母字符必须是小写,因为MD5不区分大小写。

cipher The cipher chosen by the client. This directive MUST appear exactly once if "auth-conf" is negotiated; if required and not present, authentication fails.

加密客户端选择的密码。如果协商“auth conf”,则该指令必须恰好出现一次;如果需要且不存在,身份验证将失败。

authzid The "authorization ID" as per RFC 2222, encoded in UTF-8. This directive is optional. If present, and the authenticating user has sufficient privilege, and the server supports it, then after authentication the server will use this identity for making all accesses and access checks. If the client specifies it, and the server does not support it, then the response-value will be incorrect, and authentication will fail.

根据RFC 2222对“授权ID”进行身份验证,以UTF-8编码。此指令是可选的。如果存在,并且身份验证用户具有足够的权限,并且服务器支持该权限,则在身份验证之后,服务器将使用此标识进行所有访问和访问检查。如果客户端指定了它,而服务器不支持它,那么响应值将不正确,身份验证将失败。

The size of a digest-response MUST be less than 4096 bytes.

摘要响应的大小必须小于4096字节。

2.1.2.1 Response-value
2.1.2.1 响应值

The definition of "response-value" above indicates the encoding for its value -- 32 lower case hex characters. The following definitions show how the value is computed.

上面“response value”的定义表示其值的编码——32个小写十六进制字符。以下定义显示了如何计算该值。

Although qop-value and components of digest-uri-value may be case-insensitive, the case which the client supplies in step two is preserved for the purpose of computing and verifying the response-value.

尽管qop值和摘要uri值的组件可能不区分大小写,但为了计算和验证响应值,保留了客户端在步骤2中提供的大小写。

response-value =

响应值=

         HEX( KD ( HEX(H(A1)),
                 { nonce-value, ":" nc-value, ":",
                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
        
         HEX( KD ( HEX(H(A1)),
                 { nonce-value, ":" nc-value, ":",
                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
        

If authzid is specified, then A1 is

如果指定了authzid,则为A1

      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value, ":", authzid-value }
        
      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value, ":", authzid-value }
        

If authzid is not specified, then A1 is

如果未指定authzid,则为A1

      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value }
        
      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value }
        

where

哪里

         passwd   = *OCTET
        
         passwd   = *OCTET
        

The "username-value", "realm-value" and "passwd" are encoded according to the value of the "charset" directive. If "charset=UTF-8" is present, and all the characters of either "username-value" or "passwd" are in the ISO 8859-1 character set, then it must be converted to ISO 8859-1 before being hashed. This is so that authentication databases that store the hashed username, realm and password (which is common) can be shared compatibly with HTTP, which specifies ISO 8859-1. A sample implementation of this conversion is in section 8.

根据“charset”指令的值对“username value”、“realm value”和“passwd”进行编码。如果存在“charset=UTF-8”,并且“username value”或“passwd”的所有字符都在ISO 8859-1字符集中,则必须在对其进行哈希运算之前将其转换为ISO 8859-1。这使得存储散列用户名、域和密码(这是常见的)的身份验证数据库可以与指定ISO 8859-1的HTTP兼容地共享。第8节介绍了此转换的示例实现。

If the "qop" directive's value is "auth", then A2 is:

如果“qop”指令的值为“auth”,则A2为:

      A2       = { "AUTHENTICATE:", digest-uri-value }
        
      A2       = { "AUTHENTICATE:", digest-uri-value }
        

If the "qop" value is "auth-int" or "auth-conf" then A2 is:

如果“qop”值为“auth int”或“auth conf”,则A2为:

      A2       = { "AUTHENTICATE:", digest-uri-value,
               ":00000000000000000000000000000000" }
        
      A2       = { "AUTHENTICATE:", digest-uri-value,
               ":00000000000000000000000000000000" }
        

Note that "AUTHENTICATE:" must be in upper case, and the second string constant is a string with a colon followed by 32 zeros.

注意,“AUTHENTICATE:”必须是大写,第二个字符串常量是一个冒号后跟32个零的字符串。

These apparently strange values of A2 are for compatibility with HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and the hash of the entity body to zero in the HTTP digest calculation of A2.

A2的这些明显奇怪的值是为了与HTTP兼容;在A2的HTTP摘要计算中,通过将“Method”设置为“AUTHENTICATE”,并将实体体的哈希设置为零,就可以得到它们。

Also, in the HTTP usage of Digest, several directives in the

此外,在摘要的HTTP用法中

"digest-challenge" sent by the server have to be returned by the client in the "digest-response". These are:

服务器发送的“摘要质询”必须由客户端在“摘要响应”中返回。这些是:

opaque algorithm

不透明算法

These directives are not needed when Digest is used as a SASL mechanism (i.e., MUST NOT be sent, and MUST be ignored if received).

当摘要用作SASL机制时,不需要这些指令(即,不得发送,如果收到则必须忽略)。

2.1.3 Step Three
2.1.3 第三步

The server receives and validates the "digest-response". The server checks that the nonce-count is "00000001". If it supports subsequent authentication (see section 2.2), it saves the value of the nonce and the nonce-count. It sends a message formatted as follows:

服务器接收并验证“摘要响应”。服务器检查nonce计数是否为“00000001”。如果它支持后续身份验证(请参见第2.2节),则会保存nonce和nonce计数的值。它发送的消息格式如下:

response-auth = "rspauth" "=" response-value

响应auth=“rspauth”“=”响应值

where response-value is calculated as above, using the values sent in step two, except that if qop is "auth", then A2 is

其中响应值如上所述,使用步骤2中发送的值进行计算,但如果qop为“auth”,则A2为

       A2 = { ":", digest-uri-value }
        
       A2 = { ":", digest-uri-value }
        

And if qop is "auth-int" or "auth-conf" then A2 is

如果qop是“auth int”或“auth conf”,那么A2是

       A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
        
       A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
        

Compared to its use in HTTP, the following Digest directives in the "digest-response" are unused:

与在HTTP中的使用相比,“摘要响应”中的以下摘要指令未使用:

nextnonce qop cnonce nonce-count

下一次qop cnonce当前计数

2.2 Subsequent Authentication
2.2 后续身份验证

If the client has previously authenticated to the server, and remembers the values of username, realm, nonce, nonce-count, cnonce, and qop that it used in that authentication, and the SASL profile for a protocol permits an initial client response, then it MAY perform "subsequent authentication", as defined in this section.

如果客户机之前已经向服务器进行了身份验证,并且记住了在该身份验证中使用的用户名、领域、nonce、nonce count、cnonce和qop的值,并且协议的SASL配置文件允许初始客户机响应,那么它可以执行本节中定义的“后续身份验证”。

2.2.1 Step one
2.2.1 第一步

The client uses the values from the previous authentication and sends an initial response with a string formatted and computed according to the rules for a "digest-response", as defined above, but with a nonce-count one greater than used in the last "digest-response".

客户机使用来自上一次身份验证的值,并发送一个初始响应,该响应包含一个字符串,该字符串按照上文定义的“摘要响应”规则进行格式化和计算,但其nonce count比上一次“摘要响应”中使用的值大一个。

2.2.2 Step Two
2.2.2 第二步

The server receives the "digest-response". If the server does not support subsequent authentication, then it sends a "digest-challenge", and authentication proceeds as in initial authentication. If the server has no saved nonce and nonce-count from a previous authentication, then it sends a "digest-challenge", and authentication proceeds as in initial authentication. Otherwise, the server validates the "digest-response", checks that the nonce-count is one greater than that used in the previous authentication using that nonce, and saves the new value of nonce-count.

服务器接收“摘要响应”。如果服务器不支持后续身份验证,那么它将发送一个“摘要质询”,身份验证将像初始身份验证一样进行。如果服务器没有从以前的身份验证中保存nonce和nonce计数,那么它将发送一个“摘要质询”,身份验证将按照初始身份验证的方式进行。否则,服务器将验证“摘要响应”,检查nonce计数是否比使用该nonce的上一次身份验证中使用的值大一倍,并保存nonce计数的新值。

If the response is invalid, then the server sends a "digest-challenge", and authentication proceeds as in initial authentication (and should be configurable to log an authentication failure in some sort of security audit log, since the failure may be a symptom of an attack). The nonce-count MUST NOT be incremented in this case: to do so would allow a denial of service attack by sending an out-of-order nonce-count.

如果响应无效,则服务器发送“摘要质询”,身份验证将按照初始身份验证的方式进行(并且应可配置为在某种安全审核日志中记录身份验证失败,因为失败可能是攻击的症状)。在这种情况下,nonce计数不能增加:这样做将允许通过发送无序的nonce计数进行拒绝服务攻击。

If the response is valid, the server MAY choose to deem that authentication has succeeded. However, if it has been too long since the previous authentication, or for any other reason, the server MAY send a new "digest-challenge" with a new value for nonce. The challenge MAY contain a "stale" directive with value "true", which says that the client may respond to the challenge using the password it used in the previous response; otherwise, the client must solicit the password anew from the user. This permits the server to make sure that the user has presented their password recently. (The directive name refers to the previous nonce being stale, not to the last use of the password.) Except for the handling of "stale", after sending the "digest-challenge" authentication proceeds as in the case of initial authentication.

如果响应有效,服务器可以选择认为身份验证已成功。但是,如果距离上一次身份验证时间太长,或者出于任何其他原因,服务器可能会发送一个新的“摘要质询”,其中包含一个新的nonce值。质询可能包含一个值为“true”的“stale”指令,该指令表示客户端可以使用其在上一次响应中使用的密码响应质询;否则,客户端必须向用户重新请求密码。这允许服务器确保用户最近提交了密码。(指令名称指的是之前的失效状态,而不是密码的最后一次使用。)除了“失效”的处理外,发送“摘要质询”后,身份验证与初始身份验证一样进行。

2.3 Integrity Protection
2.3 完整性保护

If the server offered "qop=auth-int" and the client responded "qop=auth-int", then subsequent messages, up to but not including the next subsequent authentication, between the client and the server

如果服务器提供“qop=auth int”且客户端响应“qop=auth int”,则客户端和服务器之间的后续消息(直到但不包括下一次后续身份验证)

MUST be integrity protected. Using as a base session key the value of H(A1) as defined above the client and server calculate a pair of message integrity keys as follows.

必须保护完整性。使用上面定义的H(A1)值作为基本会话密钥,客户端和服务器计算一对消息完整性密钥,如下所示。

The key for integrity protecting messages from client to server is:

保护从客户端到服务器的消息完整性的关键是:

   Kic = MD5({H(A1),
   "Digest session key to client-to-server signing key magic constant"})
        
   Kic = MD5({H(A1),
   "Digest session key to client-to-server signing key magic constant"})
        

The key for integrity protecting messages from server to client is:

从服务器到客户端保护消息完整性的关键是:

   Kis = MD5({H(A1),
   "Digest session key to server-to-client signing key magic constant"})
        
   Kis = MD5({H(A1),
   "Digest session key to server-to-client signing key magic constant"})
        

where MD5 is as specified in [RFC 1321]. If message integrity is negotiated, a MAC block for each message is appended to the message. The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC 2104] of the message, a 2-byte message type number in network byte order with value 1, and the 4-byte sequence number in network byte order. The message type is to allow for future extensions such as rekeying.

其中,MD5符合[RFC 1321]的规定。如果协商消息完整性,则每个消息的MAC块将附加到消息中。MAC块为16个字节:消息HMAC-MD5[RFC 2104]的前10个字节、值为1的网络字节顺序的2字节消息类型号以及网络字节顺序的4字节序列号。消息类型允许将来的扩展,例如重新键入。

   MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
   SeqNum)
        
   MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
   SeqNum)
        

where Ki is Kic for messages sent by the client and Kis for those sent by the server. The sequence number is initialized to zero, and incremented by one for each message sent.

其中Ki表示客户端发送的消息的Kic,Kis表示服务器发送的消息的Kis。序列号初始化为零,每发送一条消息,序列号递增一。

Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the received value; the message is discarded if they differ.

在接收时,计算MAC(Ki,SeqNum,msg)并与接收的值进行比较;如果它们不同,则丢弃该消息。

2.4 Confidentiality Protection
2.4 保密保护

If the server sent a "cipher-opts" directive and the client responded with a "cipher" directive, then subsequent messages between the client and the server MUST be confidentiality protected. Using as a base session key the value of H(A1) as defined above the client and server calculate a pair of message integrity keys as follows.

如果服务器发送了“cipher opts”指令,而客户端响应了“cipher”指令,则客户端和服务器之间的后续消息必须受到保密保护。使用上面定义的H(A1)值作为基本会话密钥,客户端和服务器计算一对消息完整性密钥,如下所示。

The key for confidentiality protecting messages from client to server is:

保护从客户端到服务器的消息的机密性的关键是:

   Kcc = MD5({H(A1)[0..n],
   "Digest H(A1) to client-to-server sealing key magic constant"})
        
   Kcc = MD5({H(A1)[0..n],
   "Digest H(A1) to client-to-server sealing key magic constant"})
        

The key for confidentiality protecting messages from server to client is:

保护从服务器到客户端的消息的机密性的关键是:

   Kcs = MD5({H(A1)[0..n],
   "Digest H(A1) to server-to-client sealing key magic constant"})
        
   Kcs = MD5({H(A1)[0..n],
   "Digest H(A1) to server-to-client sealing key magic constant"})
        

where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5; for "rc4-56" n is 7; for the rest n is 16. The key for the "rc-*" ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is the first 7 bytes; the key for "3des" is the first 14 bytes. The IV for "des" and "3des" is the last 8 bytes of Kcc or Kcs.

其中,MD5符合[RFC 1321]的规定。对于密码“rc4-40”,n为5;对于“rc4-56”,n为7;其余的n是16。“rc-*”密码的密钥是所有16字节的Kcc或Kcs;“des”的键是前7个字节;“3des”的键是前14个字节。“des”和“3des”的IV是Kcc或Kcs的最后8个字节。

If message confidentiality is negotiated, each message is encrypted with the chosen cipher and a MAC block is appended to the message.

如果协商消息机密性,则使用所选密码对每条消息进行加密,并在消息中附加MAC块。

The MAC block is a variable length padding prefix followed by 16 bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC 2104] of the message, a 2-byte message type number in network byte order with value 1, and the 4-byte sequence number in network byte order. If the blocksize of the chosen cipher is not 1 byte, the padding prefix is one or more octets each containing the number of padding bytes, such that total length of the encrypted part of the message is a multiple of the blocksize. The padding and first 10 bytes of the MAC block are encrypted along with the message.

MAC块是一个可变长度的填充前缀,后跟16个字节,格式如下:消息HMAC-MD5[RFC 2104]的前10个字节,值为1的网络字节顺序的2字节消息类型号,以及网络字节顺序的4字节序列号。如果所选密码的块大小不是1字节,则填充前缀是一个或多个八位字节,每个八位字节包含填充字节数,因此消息加密部分的总长度是块大小的倍数。MAC块的填充和前10个字节与消息一起加密。

   SEAL(Ki, Kc, SeqNum, msg) =
         {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001,
          SeqNum}
        
   SEAL(Ki, Kc, SeqNum, msg) =
         {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001,
          SeqNum}
        

where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for messages sent by the client and Kis and Kcs for those sent by the server. The sequence number is initialized to zero, and incremented by one for each message sent.

其中,CIPHER是所选的密码,Ki和Kc是客户机发送的消息的Kic和Kcc,Kis和Kcs是服务器发送的消息的Kis和Kcs。序列号初始化为零,每发送一条消息,序列号递增一。

Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is computed and compared with the received value; the message is discarded if they differ.

收到消息后,对消息进行解密,计算HMAC(Ki,{SeqNum,msg}),并与接收到的值进行比较;如果它们不同,则丢弃该消息。

3 Security Considerations

3安全考虑

3.1 Authentication of Clients using Digest Authentication
3.1 使用摘要身份验证对客户端进行身份验证

Digest Authentication does not provide a strong authentication mechanism, when compared to public key based mechanisms, for example. However, since it prevents chosen plaintext attacks, it is stronger than (e.g.) CRAM-MD5, which has been proposed for use with LDAP [10], POP and IMAP (see RFC 2195 [9]). It is intended to replace the much weaker and even more dangerous use of plaintext passwords; however, since it is still a password based mechanism it avoids some of the potential deployabilty issues with public-key, OTP or similar mechanisms.

例如,与基于公钥的机制相比,摘要身份验证不提供强身份验证机制。但是,由于它可以防止选定的明文攻击,因此它比(例如)CRAM-MD5更强大,CRAM-MD5已被提议用于LDAP[10]、POP和IMAP(请参见RFC 2195[9])。它旨在取代更弱甚至更危险的明文密码使用;然而,由于它仍然是一种基于密码的机制,它避免了公钥、OTP或类似机制的一些潜在部署问题。

Digest Authentication offers no confidentiality protection beyond protecting the actual password. All of the rest of the challenge and response are available to an eavesdropper, including the user's name and authentication realm.

摘要身份验证除了保护实际密码外,不提供任何保密保护。窃听者可以使用质询和响应的所有其余部分,包括用户名和身份验证域。

3.2 Comparison of Digest with Plaintext Passwords
3.2 摘要与明文密码的比较

The greatest threat to the type of transactions for which these protocols are used is network snooping. This kind of transaction might involve, for example, online access to a mail service whose use is restricted to paying subscribers. With plaintext password authentication an eavesdropper can obtain the password of the user. This not only permits him to access anything in the database, but, often worse, will permit access to anything else the user protects with the same password.

对使用这些协议的事务类型的最大威胁是网络窥探。例如,这类交易可能涉及对邮件服务的在线访问,该服务的使用仅限于付费订阅者。通过明文密码认证,窃听者可以获得用户的密码。这不仅允许他访问数据库中的任何内容,而且更糟糕的是,还允许他访问用户使用相同密码保护的任何其他内容。

3.3 Replay Attacks
3.3 攻击回放

Replay attacks are defeated if the client or the server chooses a fresh nonce for each authentication, as this specification requires.

如果客户端或服务器按照本规范的要求为每次身份验证选择一个新的nonce,则重播攻击将被击败。

3.4 Online dictionary attacks
3.4 在线词典攻击

If the attacker can eavesdrop, then it can test any overheard nonce/response pairs against a (potentially very large) list of common words. Such a list is usually much smaller than the total number of possible passwords. The cost of computing the response for each password on the list is paid once for each challenge.

如果攻击者可以窃听,那么它可以根据(可能非常大的)常用词列表测试任何无意听到的nonce/响应对。这样的列表通常比可能的密码总数小得多。为列表中的每个密码计算响应的成本为每个质询支付一次。

The server can mitigate this attack by not allowing users to select passwords that are in a dictionary.

服务器可以通过不允许用户选择字典中的密码来减轻此攻击。

3.5 Offline dictionary attacks
3.5 脱机字典攻击

If the attacker can choose the challenge, then it can precompute the possible responses to that challenge for a list of common words. Such a list is usually much smaller than the total number of possible passwords. The cost of computing the response for each password on the list is paid just once.

如果攻击者可以选择质询,那么它可以预先计算对该质询的可能响应,以获得常用词列表。这样的列表通常比可能的密码总数小得多。计算列表中每个密码的响应的成本只需支付一次。

Offline dictionary attacks are defeated if the client chooses a fresh nonce for each authentication, as this specification requires.

如果客户端按照本规范的要求为每次身份验证选择一个新的nonce,则脱机字典攻击将被击败。

3.6 Man in the Middle
3.6 中间人

Digest authentication is vulnerable to "man in the middle" (MITM) attacks. Clearly, a MITM would present all the problems of eavesdropping. But it also offers some additional opportunities to the attacker.

摘要身份验证易受“中间人”(MITM)攻击。显然,MITM会带来所有窃听问题。但它也为攻击者提供了一些额外的机会。

A possible man-in-the-middle attack would be to substitute a weaker qop scheme for the one(s) sent by the server; the server will not be able to detect this attack. For this reason, the client should always use the strongest scheme that it understands from the choices offered, and should never choose a scheme that does not meet its minimum requirements.

中间人攻击可能是用较弱的qop方案替换服务器发送的qop方案;服务器将无法检测到此攻击。因此,客户应始终使用其从所提供的选择中理解的最强方案,并且绝不应选择不符合其最低要求的方案。

3.7 Chosen plaintext attacks
3.7 选择明文攻击

A chosen plaintext attack is where a MITM or a malicious server can arbitrarily choose the challenge that the client will use to compute the response. The ability to choose the challenge is known to make cryptanalysis much easier [8].

选择明文攻击是指MITM或恶意服务器可以任意选择客户端将用于计算响应的质询。选择挑战的能力使密码分析变得更容易[8]。

However, Digest does not permit the attack to choose the challenge as long as the client chooses a fresh nonce for each authentication, as this specification requires.

但是,Digest不允许攻击选择质询,只要客户机按照本规范的要求为每个身份验证选择一个新的nonce。

3.8 Spoofing by Counterfeit Servers
3.8 假冒服务器欺骗

If a user can be led to believe that she is connecting to a host containing information protected by a password she knows, when in fact she is connecting to a hostile server, then the hostile server can obtain challenge/response pairs where it was able to partly choose the challenge. There is no known way that this can be exploited.

如果可以引导用户相信她正在连接到一个主机,该主机包含她知道的密码保护的信息,而实际上她正在连接到一个恶意服务器,那么恶意服务器可以获得质询/响应对,它可以部分选择质询。没有已知的方法可以利用这一点。

3.9 Storing passwords
3.9 存储密码

Digest authentication requires that the authenticating agent (usually the server) store some data derived from the user's name and password in a "password file" associated with a given realm. Normally this might contain pairs consisting of username and H({ username-value, ":", realm-value, ":", passwd }), which is adequate to compute H(A1) as described above without directly exposing the user's password.

摘要身份验证要求身份验证代理(通常是服务器)将从用户名和密码派生的一些数据存储在与给定域关联的“密码文件”中。通常,这可能包含由用户名和H组成的对({username value,“:”,realm value,“:”,passwd}),这足以在不直接公开用户密码的情况下如上所述计算H(A1)。

The security implications of this are that if this password file is compromised, then an attacker gains immediate access to documents on the server using this realm. Unlike, say a standard UNIX password file, this information need not be decrypted in order to access documents in the server realm associated with this file. On the other

这样做的安全含义是,如果此密码文件被破坏,则攻击者可以立即使用此域访问服务器上的文档。与标准UNIX密码文件不同,访问与此文件关联的服务器域中的文档时,不需要解密此信息。另一方面

hand, decryption, or more likely a brute force attack, would be necessary to obtain the user's password. This is the reason that the realm is part of the digested data stored in the password file. It means that if one Digest authentication password file is compromised, it does not automatically compromise others with the same username and password (though it does expose them to brute force attack).

获取用户密码需要手动、解密或更可能的暴力攻击。这就是域是存储在密码文件中的摘要数据的一部分的原因。这意味着,如果一个摘要身份验证密码文件被破坏,它不会自动破坏具有相同用户名和密码的其他文件(尽管它会使它们遭受暴力攻击)。

There are two important security consequences of this. First the password file must be protected as if it contained plaintext passwords, because for the purpose of accessing documents in its realm, it effectively does.

这有两个重要的安全后果。首先,密码文件必须像包含明文密码一样受到保护,因为为了访问其领域中的文档,它实际上是这样做的。

A second consequence of this is that the realm string should be unique among all realms that any single user is likely to use. In particular a realm string should include the name of the host doing the authentication.

第二个结果是,领域字符串在任何单个用户可能使用的所有领域中都应该是唯一的。尤其是领域字符串应该包括进行身份验证的主机的名称。

3.10 Multiple realms
3.10 多领域

Use of multiple realms may mean both that compromise of a the security database for a single realm does not compromise all security, and that there are more things to protect in order to keep the whole system secure.

使用多个领域可能意味着危害单个领域的安全数据库不会危害所有安全性,而且为了保持整个系统的安全,还有更多的东西需要保护。

3.11 Summary
3.11 总结

By modern cryptographic standards Digest Authentication is weak, compared to (say) public key based mechanisms. But for a large range of purposes it is valuable as a replacement for plaintext passwords. Its strength may vary depending on the implementation.

根据现代密码标准,与(比如)基于公钥的机制相比,摘要认证很弱。但在很多情况下,它作为明文密码的替代品是很有价值的。其强度可能因实施情况而异。

4 Example

4例

This example shows the use of the Digest SASL mechanism with the IMAP4 AUTHENTICATE command [RFC 2060].

此示例显示了将摘要SASL机制与IMAP4 AUTHENTICATE命令[RFC 2060]一起使用。

In this example, "C:" and "S:" represent a line sent by the client or server respectively including a CRLF at the end. Linebreaks and indentation within a "C:" or "S:" are editorial and not part of the protocol. The password in this example was "secret". Note that the base64 encoding of the challenges and responses is part of the IMAP4 AUTHENTICATE command, not part of the Digest specification itself.

在本例中,“C:”和“S:”分别表示客户端或服务器发送的一行,末尾包括一个CRLF。“C:”或“S:”中的换行符和缩进是编辑性的,不是协议的一部分。本例中的密码为“secret”。请注意,质询和响应的base64编码是IMAP4 AUTHENTICATE命令的一部分,而不是摘要规范本身的一部分。

    S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9
    C: c CAPABILITY
    S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA
                UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN
    S: c OK Completed
        
    S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9
    C: c CAPABILITY
    S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA
                UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN
    S: c OK Completed
        
    C: a AUTHENTICATE DIGEST-MD5
    S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
         RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
         cnNldD11dGYtOA==
    C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
       QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
       MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
       ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
       ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
    S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
    C:
    S: a OK User logged in
    ---
        
    C: a AUTHENTICATE DIGEST-MD5
    S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
         RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
         cnNldD11dGYtOA==
    C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
       QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
       MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
       ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
       ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
    S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
    C:
    S: a OK User logged in
    ---
        

The base64-decoded version of the SASL exchange is:

SASL exchange的base64解码版本为:

    S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
       algorithm=md5-sess,charset=utf-8
    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
       nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
       digest-uri="imap/elwood.innosoft.com",
       response=d388dad90d4bbd760a152321f2143af7,qop=auth
    S: rspauth=ea40f60335c427b5527b84dbabcdfffd
        
    S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
       algorithm=md5-sess,charset=utf-8
    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
       nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
       digest-uri="imap/elwood.innosoft.com",
       response=d388dad90d4bbd760a152321f2143af7,qop=auth
    S: rspauth=ea40f60335c427b5527b84dbabcdfffd
        

The password in this example was "secret".

本例中的密码为“secret”。

This example shows the use of the Digest SASL mechanism with the ACAP, using the same notational conventions and password as in the previous example. Note that ACAP does not base64 encode and uses fewer round trips that IMAP4.

此示例显示了在ACAP中使用摘要SASL机制,使用与前一示例相同的符号约定和密码。请注意,ACAP不使用base64编码,使用的往返次数比IMAP4少。

    S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5"
               "DIGEST-MD5" "PLAIN")
    C: a AUTHENTICATE "DIGEST-MD5"
    S: + {94}
    S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth",
       algorithm=md5-sess,charset=utf-8
    C: {206}
    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
       nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m",
       digest-uri="acap/elwood.innosoft.com",
       response=6084c6db3fede7352c551284490fd0fc,qop=auth
    S: a OK (SASL {40}
    S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE
    Completed"
    ---
        
    S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5"
               "DIGEST-MD5" "PLAIN")
    C: a AUTHENTICATE "DIGEST-MD5"
    S: + {94}
    S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth",
       algorithm=md5-sess,charset=utf-8
    C: {206}
    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
       nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m",
       digest-uri="acap/elwood.innosoft.com",
       response=6084c6db3fede7352c551284490fd0fc,qop=auth
    S: a OK (SASL {40}
    S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE
    Completed"
    ---
        

The server uses the values of all the directives, plus knowledge of the users password (or the hash of the user's name, server's realm and the user's password) to verify the computations above. If they check, then the user has authenticated.

服务器使用所有指令的值,加上用户密码的知识(或用户名、服务器域和用户密码的散列)来验证上述计算。如果他们进行了检查,则用户已通过身份验证。

5 References

5参考文献

[Digest] Franks, J., et al., "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999.

[摘要]Franks,J.等人,“HTTP认证:基本和摘要访问认证”,RFC 26171999年6月。

[ISO-8859] ISO-8859. International Standard--Information Processing-- 8-bit Single-Byte Coded Graphic Character Sets -- Part 1: Latin alphabet No. 1, ISO-8859-1:1987. Part 2: Latin alphabet No. 2, ISO-8859-2, 1987. Part 3: Latin alphabet No. 3, ISO-8859-3, 1988. Part 4: Latin alphabet No. 4, ISO-8859-4, 1988. Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988. Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987. Part 7: Latin/Greek alphabet, ISO-8859-7, 1987. Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988. Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.

[ISO-8859]ISO-8859。国际标准信息处理8位单字节编码图形字符集第1部分:拉丁字母表1。第2部分:拉丁字母表2,ISO-8859-21987。第3部分:拉丁字母表3,ISO-8859-31988。第4部分:拉丁字母表4,ISO-8859-41988。第5部分:拉丁/西里尔字母,ISO-8859-51988。第6部分:拉丁/阿拉伯语字母表,ISO-8859-61987。第7部分:拉丁/希腊字母表,ISO-8859-71987。第8部分:拉丁/希伯来字母表,ISO-8859-81988。第9部分:拉丁字母表5,ISO-8859-91990。

[RFC 822] Crocker, D., "Standard for The Format of ARPA Internet Text Messages," STD 11, RFC 822, August 1982.

[RFC 822]Crocker,D.,“ARPA互联网文本信息格式标准”,STD 11,RFC 822,1982年8月。

[RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.

[RFC 1321]Rivest,R.,“MD5消息摘要算法”,RFC 1321,1992年4月。

[RFC 2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996.

[RFC 2047]Moore,K.,“MIME(多用途互联网邮件扩展)第三部分:非ASCII文本的消息头扩展”,RFC 2047,1996年11月。

[RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2052, October 1996.

[RFC 2052]Gulbrandsen,A.和P.Vixie,“用于指定服务位置(DNS SRV)的DNS RR”,RFC 2052,1996年10月。

[RFC 2060] Crispin, M., "Internet Message Access Protocol - Version 4rev1", RFC 2060, December 1996.

[RFC 2060]Crispin,M.,“互联网消息访问协议-版本4rev1”,RFC 2060,1996年12月。

[RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.

[RFC 2104]Krawczyk,H.,Bellare,M.和R.Canetti,“HMAC:用于消息认证的键控哈希”,RFC 2104,1997年2月。

[RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP AUTHorize Extension for Simple Challenge/Response", RFC 2195, September 1997.

[RFC 2195]Klensin,J.,Catoe,R.和P.Krumviede,“简单质询/响应的IMAP/POP授权扩展”,RFC 2195,1997年9月。

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

[RFC 2119]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[RFC 2222] Myers, J., "Simple Authentication and Security Layer (SASL)", RFC 2222, October 1997.

[RFC2222]迈尔斯,J.,“简单认证和安全层(SASL)”,RFC22221997年10月。

[USASCII] US-ASCII. Coded Character Set - 7-Bit American Standard Code for Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986.

[USASCII]US-ASCII。编码字符集.信息交换用7位美国标准代码。标准ANSI X3.4-1986,ANSI,1986。

6 Authors' Addresses

6作者地址

Paul Leach Microsoft 1 Microsoft Way Redmond, WA 98052

Paul Leach微软1号微软路雷德蒙德,华盛顿州98052

   EMail: paulle@microsoft.com
        
   EMail: paulle@microsoft.com
        

Chris Newman Innosoft International, Inc. 1050 Lakes Drive West Covina, CA 91790 USA

Chris Newman Innosoft International,Inc.美国加利福尼亚州西科维纳湖大道1050号,邮编:91790

   EMail: chris.newman@innosoft.com
        
   EMail: chris.newman@innosoft.com
        

7 ABNF

7荷兰银行

What follows is the definition of the notation as is used in the HTTP/1.1 specification (RFC 2616) and the HTTP authentication specification (RFC 2617); it is reproduced here for ease of reference. Since it is intended that a single Digest implementation can support both HTTP and SASL-based protocols, the same notation is used in both to facilitate comparison and prevention of unwanted differences. Since it is cut-and-paste from the HTTP specifications, not all productions may be used in this specification. It is also not quite legal ABNF; again, the errors were copied from the HTTP specifications.

以下是HTTP/1.1规范(RFC 2616)和HTTP认证规范(RFC 2617)中使用的符号定义;为了便于参考,这里复制了它。由于单个摘要实现可以支持基于HTTP和SASL的协议,因此在这两种协议中使用相同的符号,以便于比较和防止不必要的差异。由于它是从HTTP规范中剪切和粘贴的,因此本规范中不能使用所有产品。这也不完全合法;同样,错误是从HTTP规范复制的。

7.1 Augmented BNF
7.1 补充反馈方式

All of the mechanisms specified in this document are described in both prose and an augmented Backus-Naur Form (BNF) similar to that used by RFC 822 [RFC 822]. Implementers will need to be familiar with the notation in order to understand this specification.

本文件中规定的所有机制均以散文和类似于RFC 822[RFC 822]所用的增广巴科斯-诺尔形式(BNF)进行了描述。实现者需要熟悉符号才能理解该规范。

The augmented BNF includes the following constructs:

扩充BNF包括以下结构:

name = definition The name of a rule is simply the name itself (without any enclosing "<" and ">") and is separated from its definition by the equal "=" character. White space is only significant in that indentation of continuation lines is used to indicate a rule definition that spans more than one line. Certain basic rules are in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle brackets are used within definitions whenever their presence will facilitate discerning the use of rule names.

名称=定义规则的名称只是名称本身(没有任何封闭的“<”和“>”),并用相等的“=”字符与其定义分开。只有在连续行的缩进用于指示跨越多行的规则定义时,空格才有意义。某些基本规则是大写的,如SP、LWS、HT、CRLF、DIGIT、ALPHA等。如果有角括号,则在定义中使用角括号,以便于识别规则名称的使用。

"literal" Quotation marks surround literal text. Unless stated otherwise, the text is case-insensitive.

“文字”引号围绕文字。除非另有说明,否则文本不区分大小写。

rule1 | rule2 Elements separated by a bar ("|") are alternatives, e.g., "yes | no" will accept yes or no.

规则1 |规则2元素之间用条(“|”)分隔是可选的,例如,“是|否”将接受是或否。

(rule1 rule2) Elements enclosed in parentheses are treated as a single element. Thus, "(elem (foo | bar) elem)" allows the token sequences "elem foo elem" and "elem bar elem".

(规则1规则2)括号内的元素被视为单个元素。因此,“(elem(foo | bar)elem)”允许令牌序列“elem foo elem”和“elem bar elem”。

*rule The character "*" preceding an element indicates repetition. The full form is "<n>*<m>element" indicating at least <n> and at most <m> occurrences of element. Default values are 0 and infinity so that "*(element)" allows any number, including zero; "1*element" requires at least one; and "1*2element" allows one or two.

*规则元素前面的字符“*”表示重复。完整形式为“<n>*<m>元素”,表示元素至少出现<n>次,最多出现<m>次。默认值为0和无穷大,因此“*(元素)”允许任何数字,包括零;“1*元素”至少需要一个;“1*2元素”允许一个或两个。

[rule] Square brackets enclose optional elements; "[foo bar]" is equivalent to "*1(foo bar)".

[规则]方括号内包含可选元素;“[foo-bar]”相当于“*1(foo-bar)”。

N rule Specific repetition: "<n>(element)" is equivalent to "<n>*<n>(element)"; that is, exactly <n> occurrences of (element). Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three alphabetic characters.

N特定于规则的重复:“<N>(元素)”相当于“<N>*<N>(元素)”;也就是说,正好<n>出现(元素)。因此,2DIGIT是一个2位数字,3ALPHA是一个由三个字母组成的字符串。

   #rule
      A construct "#" is defined, similar to "*", for defining lists of
      elements. The full form is "<n>#<m>element" indicating at least
      <n> and at most <m> elements, each separated by one or more commas
      (",") and OPTIONAL linear white space (LWS). This makes the usual
      form of lists very easy; a rule such as
        
   #rule
      A construct "#" is defined, similar to "*", for defining lists of
      elements. The full form is "<n>#<m>element" indicating at least
      <n> and at most <m> elements, each separated by one or more commas
      (",") and OPTIONAL linear white space (LWS). This makes the usual
      form of lists very easy; a rule such as
        

( *LWS element *( *LWS "," *LWS element )) can be shown as 1#element Wherever this construct is used, null elements are allowed, but do not contribute to the count of elements present. That is, "(element), , (element) " is permitted, but counts as only two elements. Therefore, where at least one element is required, at least one non-null element MUST be present. Default values are 0 and infinity so that "#element" allows any number, including zero; "1#element" requires at least one; and "1#2element" allows one or two.

(*LWS元素*(*LWS“,“*LWS元素))可以显示为1#元素。无论在何处使用此构造,都允许使用空元素,但不影响当前元素的计数。也就是说,允许使用“(元素),(元素)”,但仅计为两个元素。因此,当至少需要一个元素时,必须至少存在一个非空元素。默认值为0和无穷大,因此“#元素”允许任何数字,包括零;“1#元素”至少需要一个;“1#2element”允许一个或两个。

; comment A semi-colon, set off some distance to the right of rule text, starts a comment that continues to the end of line. This is a simple way of including useful notes in parallel with the specifications.

; 注释分号,在规则文本右侧留出一定距离,开始一条注释,该注释一直延续到行尾。这是一种简单的方法,可以在规范中同时包含有用的注释。

implied *LWS The grammar described by this specification is word-based. Except where noted otherwise, linear white space (LWS) can be included between any two adjacent words (token or quoted-string), and between adjacent words and separators, without changing the interpretation of a field. At least one delimiter (LWS and/or separators) MUST exist between any two tokens (for the definition of "token" below), since they would otherwise be interpreted as a single token.

默示*LWS本规范描述的语法是基于单词的。除非另有说明,否则线性空白(LWS)可以包括在任意两个相邻单词(标记或带引号的字符串)之间,以及相邻单词和分隔符之间,而不改变字段的解释。任何两个令牌(对于下面的“令牌”定义)之间必须至少存在一个分隔符(LW和/或分隔符),否则它们将被解释为单个令牌。

7.2 Basic Rules
7.2 基本规则

The following rules are used throughout this specification to describe basic parsing constructs. The US-ASCII coded character set is defined by ANSI X3.4-1986 [USASCII].

本规范中使用以下规则来描述基本的解析构造。US-ASCII编码字符集由ANSI X3.4-1986[USASCII]定义。

       OCTET          = <any 8-bit sequence of data>
       CHAR           = <any US-ASCII character (octets 0 - 127)>
       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
       ALPHA          = UPALPHA | LOALPHA
       DIGIT          = <any US-ASCII digit "0".."9">
       CTL            = <any US-ASCII control character
                        (octets 0 - 31) and DEL (127)>
       CR             = <US-ASCII CR, carriage return (13)>
       LF             = <US-ASCII LF, linefeed (10)>
       SP             = <US-ASCII SP, space (32)>
       HT             = <US-ASCII HT, horizontal-tab (9)>
       <">            = <US-ASCII double-quote mark (34)>
       CRLF           = CR LF
        
       OCTET          = <any 8-bit sequence of data>
       CHAR           = <any US-ASCII character (octets 0 - 127)>
       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
       ALPHA          = UPALPHA | LOALPHA
       DIGIT          = <any US-ASCII digit "0".."9">
       CTL            = <any US-ASCII control character
                        (octets 0 - 31) and DEL (127)>
       CR             = <US-ASCII CR, carriage return (13)>
       LF             = <US-ASCII LF, linefeed (10)>
       SP             = <US-ASCII SP, space (32)>
       HT             = <US-ASCII HT, horizontal-tab (9)>
       <">            = <US-ASCII double-quote mark (34)>
       CRLF           = CR LF
        

All linear white space, including folding, has the same semantics as SP. A recipient MAY replace any linear white space with a single SP before interpreting the field value or forwarding the message downstream.

所有线性空白(包括折叠)与SP具有相同的语义。在解释字段值或向下游转发消息之前,收件人可以用单个SP替换任何线性空白。

       LWS            = [CRLF] 1*( SP | HT )
        
       LWS            = [CRLF] 1*( SP | HT )
        

The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [ISO 8859] only when encoded according to the rules of RFC 2047 [RFC 2047].

文本规则仅用于描述性字段内容和值,这些内容和值不打算由消息解析器解释。只有在根据RFC 2047[RFC 2047]的规则进行编码时,*文本的字才能包含ISO-8859-1[ISO 8859]以外的字符集中的字符。

       TEXT           = <any OCTET except CTLs,
                        but including LWS>
        
       TEXT           = <any OCTET except CTLs,
                        but including LWS>
        

A CRLF is allowed in the definition of TEXT only as part of a header field continuation. It is expected that the folding LWS will be replaced with a single SP before interpretation of the TEXT value.

在文本定义中,CRLF仅允许作为标题字段延续的一部分。预计在解释文本值之前,折叠LWS将替换为单个SP。

Hexadecimal numeric characters are used in several protocol elements.

在几个协议元素中使用十六进制数字字符。

       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
        
       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
        

Many HTTP/1.1 header field values consist of words separated by LWS or special characters. These special characters MUST be in a quoted string to be used within a parameter value.

许多HTTP/1.1头字段值由LWS或特殊字符分隔的单词组成。这些特殊字符必须位于带引号的字符串中,才能在参数值中使用。

       token          = 1*<any CHAR except CTLs or separators>
       separators     = "(" | ")" | "<" | ">" | "@"
                      | "," | ";" | ":" | "\" | <">
                      | "/" | "[" | "]" | "?" | "="
                      | "{" | "}" | SP | HT
        
       token          = 1*<any CHAR except CTLs or separators>
       separators     = "(" | ")" | "<" | ">" | "@"
                      | "," | ";" | ":" | "\" | <">
                      | "/" | "[" | "]" | "?" | "="
                      | "{" | "}" | SP | HT
        

A string of text is parsed as a single word if it is quoted using double-quote marks.

如果使用双引号将文本字符串引用,则将其解析为单个单词。

      quoted-string  = ( <"> qdstr-val <"> )
      qdstr-val      = *( qdtext | quoted-pair )
      qdtext         = <any TEXT except <">>
        
      quoted-string  = ( <"> qdstr-val <"> )
      qdstr-val      = *( qdtext | quoted-pair )
      qdtext         = <any TEXT except <">>
        

Note that LWS is NOT implicit between the double-quote marks (<">) surrounding a qdstr-val and the qdstr-val; any LWS will be considered part of the qdstr-val. This is also the case for quotation marks surrounding any other construct.

请注意,LWS在围绕QDSR val的双引号(<“>)和QDSR val之间不是隐式的;任何LWS都将被视为QDSR-val的一部分。围绕任何其他构造的引号也是如此。

The backslash character ("\") MAY be used as a single-character quoting mechanism only within qdstr-val and comment constructs.

反斜杠字符(\)只能在qdstr val和comment构造中用作单字符引用机制。

quoted-pair = "\" CHAR

quoted pair=“\”字符

The value of this construct is CHAR. Note that an effect of this rule is that backslash must be quoted.

此构造的值为CHAR。请注意,此规则的效果是必须引用反斜杠。

8 Sample Code

8示例代码

The sample implementation in [Digest] also applies to DIGEST-MD5.

[Digest]中的示例实现也适用于Digest-MD5。

The following code implements the conversion from UTF-8 to 8859-1 if necessary.

如有必要,以下代码实现从UTF-8到8859-1的转换。

    /* if the string is entirely in the 8859-1 subset of UTF-8, then
     * translate to 8859-1 prior to MD5
     */
    void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base,
        int len)
    {
        const unsigned char *scan, *end;
        unsigned char cbuf;
        
    /* if the string is entirely in the 8859-1 subset of UTF-8, then
     * translate to 8859-1 prior to MD5
     */
    void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base,
        int len)
    {
        const unsigned char *scan, *end;
        unsigned char cbuf;
        
        end = base + len;
        for (scan = base; scan < end; ++scan) {
            if (*scan > 0xC3) break; /* abort if outside 8859-1 */
            if (*scan >= 0xC0 && *scan <= 0xC3) {
                if (++scan == end || *scan < 0x80 || *scan > 0xBF)
                    break;
            }
        }
        /* if we found a character outside 8859-1, don't alter string
         */
        if (scan < end) {
            MD5Update(ctx, base, len);
            return;
        }
        
        end = base + len;
        for (scan = base; scan < end; ++scan) {
            if (*scan > 0xC3) break; /* abort if outside 8859-1 */
            if (*scan >= 0xC0 && *scan <= 0xC3) {
                if (++scan == end || *scan < 0x80 || *scan > 0xBF)
                    break;
            }
        }
        /* if we found a character outside 8859-1, don't alter string
         */
        if (scan < end) {
            MD5Update(ctx, base, len);
            return;
        }
        
        /* convert to 8859-1 prior to applying hash
         */
        do {
            for (scan = base; scan < end && *scan < 0xC0; ++scan)
                ;
            if (scan != base) MD5Update(ctx, base, scan - base);
            if (scan + 1 >= end) break;
            cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
            MD5Update(ctx, &cbuf, 1);
        
        /* convert to 8859-1 prior to applying hash
         */
        do {
            for (scan = base; scan < end && *scan < 0xC0; ++scan)
                ;
            if (scan != base) MD5Update(ctx, base, scan - base);
            if (scan + 1 >= end) break;
            cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
            MD5Update(ctx, &cbuf, 1);
        
            base = scan + 2;
        } while (base < end);
    }
        
            base = scan + 2;
        } while (base < end);
    }
        

9 Full Copyright Statement

9完整版权声明

Copyright (C) The Internet Society (2000). All Rights Reserved.

版权所有(C)互联网协会(2000年)。版权所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

本文件及其译本可复制并提供给他人,对其进行评论或解释或协助其实施的衍生作品可全部或部分编制、复制、出版和分发,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文件本身,例如删除版权通知或对互联网协会或其他互联网组织的引用,除非出于制定互联网标准的需要,在这种情况下,必须遵循互联网标准过程中定义的版权程序,或根据需要将其翻译成英语以外的其他语言。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上述授予的有限许可是永久性的,互联网协会或其继承人或受让人不会撤销。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

本文件和其中包含的信息是按“原样”提供的,互联网协会和互联网工程任务组否认所有明示或暗示的保证,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。