3. Digest Access Authentication Scheme (摘要访问认证方案)
3.1 Introduction (简介)
3.1.1 Purpose (目的)
被称为"HTTP/1.0"的协议包括基本访问认证方案 (Basic Access Authentication Scheme) [1] 的规范。该方案不被认为是安全的用户认证方法,因为用户名和密码以未加密的形式在网络上传递。本节提供了一种不以明文发送密码的方案的规范,称为"摘要访问认证" (Digest Access Authentication)。
摘要访问认证方案并不打算成为万维网安全需求的完整答案。该方案不提供消息内容的加密。其意图只是创建一种避免基本认证最严重缺陷的访问认证方法。
3.1.2 Overall Operation (整体操作)
与基本访问认证类似,摘要方案基于简单的挑战-响应范式 (Challenge-Response Paradigm)。摘要方案使用nonce值进行挑战。有效响应包含用户名、密码、给定的nonce值、HTTP方法和请求的URI的校验和(默认情况下为MD5校验和)。通过这种方式,密码永远不会以明文发送。就像基本方案一样,用户名和密码必须以本文档未涉及的某种方式预先安排。
3.1.3 Representation of digest values (摘要值的表示)
可选头允许服务器指定用于创建校验和或摘要的算法。默认情况下使用MD5算法,这是本文档中描述的唯一算法。
就本文档而言,128位的MD5摘要表示为32个ASCII可打印字符。128位摘要中的位从最高有效位到最低有效位,每次四位转换为其ASCII表示,如下所示。每四位由其熟悉的十六进制表示法表示,使用字符0123456789abcdef。也就是说,二进制0000由字符'0'表示,0001由'1'表示,依此类推,直到1111表示为'f'。
3.1.4 Limitations (限制)
本文档中描述的摘要认证方案存在许多已知的限制。它旨在作为基本认证的替代品,仅此而已。它是一个基于密码的系统,(在服务器端)遭受任何密码系统的所有相同问题。特别是,本协议中没有规定用户和服务器之间建立用户密码的初始安全安排。
用户和实现者应该意识到,该协议不如Kerberos安全,也不如任何客户端私钥方案安全。尽管如此,它比什么都没有好,比telnet和ftp通常使用的好,也比基本认证好。
3.2 Specification of Digest Headers (摘要头部规范)
摘要访问认证方案在概念上类似于基本方案。修改后的WWW-Authenticate头行和Authorization头行的格式如下所述。此外,还指定了一个新头Authentication-Info。
3.2.1 The WWW-Authenticate Response Header (WWW-Authenticate响应头)
如果服务器收到对访问受保护对象的请求,并且未发送可接受的Authorization头,则服务器以"401 Unauthorized"状态码响应,并按照上面定义的框架使用WWW-Authenticate头,对于摘要方案的使用如下:
challenge = "Digest" digest-challenge
digest-challenge = 1#( realm | [ domain ] | nonce |
[ opaque ] |[ stale ] | [ algorithm ] |
[ qop-options ] | [auth-param] )
domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
nonce = "nonce" "=" nonce-value
nonce-value = quoted-string
opaque = "opaque" "=" quoted-string
stale = "stale" "=" ( "true" | "false" )
algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | token )
qop-options = "qop" "=" <"> 1#qop-value <">
qop-value = "auth" | "auth-int" | token
上述指令值的含义如下:
realm (领域)
- 要显示给用户的字符串,以便他们知道要使用哪个用户名和密码。此字符串应至少包含执行认证的主机名称,并可能另外指示可能有权访问的用户集合。例如"[email protected]"。
domain (域)
- 一个带引号的、空格分隔的URI列表,如RFC XURI [7] 中所指定,定义保护空间。如果URI是abs_path,则它相对于被访问服务器的规范根URL(参见上面的第1.2节)。此列表中的absoluteURI可能指向与被访问服务器不同的服务器。客户端可以使用此列表来确定可以发送相同认证信息的URI集:任何具有此列表中的URI作为前缀(在两者都变为绝对后)的URI都可以假定在同一保护空间中。如果省略此指令或其值为空,则客户端应假定保护空间由响应服务器上的所有URI组成。
- 此指令在Proxy-Authenticate头中没有意义,对于代理,保护空间始终是整个代理;如果存在,应忽略它。
nonce (随机数)
- 服务器指定的数据字符串,每次发出401响应时都应唯一生成。建议此字符串为base64或十六进制数据。具体来说,由于字符串作为带引号的字符串在头行中传递,因此不允许使用双引号字符。
- nonce的内容取决于实现。实现的质量取决于良好的选择。例如,nonce可以构造为以下内容的base64编码:
其中time-stamp是服务器生成的时间或其他不重复的值,ETag是与请求实体关联的HTTP ETag头的值,private-key是只有服务器知道的数据。使用这种形式的nonce,服务器将在收到客户端认证头后重新计算哈希部分,如果它与该头中的nonce不匹配或time-stamp值不够新,则拒绝请求。通过这种方式,服务器可以限制nonce的有效时间。包含ETag可以防止对资源更新版本的重放请求。(注意:在nonce中包含客户端的IP地址似乎可以为服务器提供将nonce的重用限制为最初获得它的同一客户端的能力。但是,这会破坏代理群,其中来自单个用户的请求通常通过群中的不同代理。此外,IP地址欺骗并不那么困难。)
time-stamp H(time-stamp ":" ETag ":" private-key) - 实现可能选择不接受先前使用的nonce或先前使用的摘要,以防止重放攻击。或者,实现可能选择对POST或PUT请求使用一次性nonce或摘要,对GET请求使用时间戳。有关所涉及问题的更多详细信息,请参见本文档的第4节。
- nonce对客户端是不透明的。
opaque (不透明)
- 服务器指定的数据字符串,客户端应在同一保护空间中URI的后续请求的Authorization头中原封不动地返回。建议此字符串为base64或十六进制数据。
stale (过期)
- 一个标志,指示客户端的先前请求被拒绝,因为nonce值已过期。如果stale为TRUE(不区分大小写),客户端可能希望简单地使用新的加密响应重试请求,而无需重新提示用户输入新的用户名和密码。服务器应仅在收到nonce无效但该nonce的摘要有效的请求时将stale设置为TRUE(表明客户端知道正确的用户名/密码)。如果stale为FALSE,或除TRUE之外的任何内容,或stale指令不存在,则用户名和/或密码无效,必须获取新值。
algorithm (算法)
- 指示用于生成摘要和校验和的一对算法的字符串。如果不存在,则假定为"MD5"。如果不理解该算法,则应忽略挑战(如果有多个挑战,则使用不同的挑战)。
- 在本文档中,通过将摘要算法应用于具有密钥"secret"的数据"data"获得的字符串将表示为KD(secret, data),通过将校验和算法应用于数据"data"获得的字符串将表示为H(data)。符号unq(X)表示带引号的字符串X的值,不包括周围的引号。
- 对于"MD5"和"MD5-sess"算法:
和
H(data) = MD5(data)即,摘要是密钥与冒号连接,再与数据连接的MD5。"MD5-sess"算法旨在允许高效的第三方认证服务器;有关使用差异,请参见第3.2.2.2节中的描述。KD(secret, data) = H(concat(secret, ":", data))
qop-options (质量保护选项)
- 此指令是可选的,但仅为了与RFC 2069 [6] 向后兼容而设为可选;符合此版本摘要方案的所有实现都应该 (SHOULD) 使用它。如果存在,它是一个带引号的字符串,包含一个或多个令牌,指示服务器支持的"质量保护"值。值"auth"表示认证;值"auth-int"表示具有完整性保护的认证;有关这些选项含义的详细信息,请参见第3.2.2.2节中的描述。未识别的选项必须 (MUST) 被忽略。
3.2.2 The Authorization Request Header (Authorization请求头)
客户端通过在请求中包含Authorization头字段来响应WWW-Authenticate挑战。Authorization字段值的内容取决于所选的摘要算法。
credentials = "Digest" digest-response
digest-response = 1#( username | realm | nonce | digest-uri
| response | [ algorithm ] | [cnonce] |
[opaque] | [message-qop] |
[nonce-count] | [auth-param] )
username = "username" "=" username-value
username-value = quoted-string
digest-uri = "uri" "=" digest-uri-value
digest-uri-value = request-uri
message-qop = "qop" "=" qop-value
cnonce = "cnonce" "=" cnonce-value
cnonce-value = nonce-value
nonce-count = "nc" "=" nc-value
nc-value = 8LHEX
response = "response" "=" request-digest
request-digest = <"> 32LHEX <">
LHEX = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
"8" | "9" | "a" | "b" | "c" | "d" | "e" | "f"
**response (响应)**值的计算方式在第3.2.2.1节中描述。
3.2.3 The Authentication-Info Header (Authentication-Info头)
Authentication-Info头字段可以 (MAY) 由服务器在成功认证后的响应中使用,以传达有关成功认证的信息。此头字段对于"auth-int"质量保护特别有用。
AuthenticationInfo = "Authentication-Info" ":" auth-info
auth-info = 1#(nextnonce | [ message-qop ]
| [ response-auth ] | [ cnonce ]
| [nonce-count] )
nextnonce = "nextnonce" "=" nonce-value
response-auth = "rspauth" "=" response-digest
response-digest = <"> *LHEX <">
3.3 Digest Operation (摘要操作)
摘要访问认证的操作如下。客户端向服务器发出请求,服务器以401响应进行挑战,提供nonce和其他参数。客户端使用这些参数计算response值,并在后续请求中将其与其他信息一起发送到服务器。服务器验证response值,如果正确,则授予访问权限。
3.4 Security Protocol Negotiation (安全协议协商)
服务器可以在WWW-Authenticate头中提供多个挑战,每个挑战使用不同的认证方案。客户端应选择它支持的最强方案。
3.5 Example (示例)
以下示例假设访问受保护的文档需要认证。服务器以401响应进行挑战:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="[email protected]",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
客户端可能使用以下Authorization头进行响应:
Authorization: Digest username="Mufasa",
realm="[email protected]",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
qop=auth,
nc=00000001,
cnonce="0a4f113b",
response="6629fae49393a05397450978507c4ef1",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
3.6 Proxy-Authentication and Proxy-Authorization (代理认证和代理授权)
代理认证和授权的工作方式与源服务器认证和授权类似,但使用Proxy-Authenticate和Proxy-Authorization头字段。代理必须 (MUST) 完全透明地处理客户端与源服务器之间的认证。