登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: RFC2617- HTTP Authentication自译本[转]     [回主站]     [分站链接]
标题
RFC2617- HTTP Authentication自译本[转]
clq
浏览(2) + 2005-08-11 21:21:19 发表 编辑

关键字:

RFC2617有一个非常重要的应用,就是访问hotmail的邮箱。因此找到了这个文章我就立即贴了出来。同时给出原英文版本的以作对照。文档中有极其宝贵的实现代码,但它们在windows平台上编译时是要作些修改的。主要是unsigned char *与char *及C与C++编译后函数名的一些问题。
--------------------------------------------------------
RFC2617- HTTP Authentication自译本-(1)


Network Working Group                             J. Franks

Request for Comments: 2617               Northwestern University

Obsoletes: 2069                             P. Hallam-Baker

Category: Standards Track                       Verisign, Inc.

                                        J. Hostetler

                                      AbiSource, Inc.

                                        S. Lawrence

                                  Agranat Systems, Inc.

                                          P. Leach

                                  Microsoft Corporation

                                        A. Luotonen

                        Netscape Communications Corporation

                                        L. Stewart

                                    Open Market, Inc.

                                          June 1999





    HTTP Authentication: Basic and Digest Access Authentication



备忘(Status of this Memo)

    本文档跟踪记录Internet团体为完善协议而进行的讨论、建议。详情请参见官方文件(STD1)。本文可任意分发。



版权声明(Copyright Notice)



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



摘要(Abstract)

   

    “HTTP/1.0”中包括基本访问鉴别方案(Basic Access Authentication scheme)。该方案不是安全的用户授权方法(除非与其它安全方法联合使用,如SSL[5]),因为其用户名和口令在网络上是以明文方式传送的。

    本文档还提供了HTTP鉴别框架的规范,有关原始的基本鉴别方案和基于哈希加密的方案的内容,请参见分类访问鉴别(Digest Acccess Authentication)。从RFC2069公布以来,其中涉及的一些可选元素因为出现问题而被移出;而还有一些新的元素因为兼容性的原因而被加入,这些新元素虽然是可选的,但还是强烈建议使用的,因而,RFC2069[6]最终可能会被本规范所替代。

Franks, et al.         Standards Track               [Page 1]


    与基本方式类似的是,分类鉴别授权对通讯双方都知道的秘密(如口令)进行校验;而与基本方式不同的是,该校验方式中的口令不以明文方式传输,而这正是基本方式的最大弱点。正象其它大多数授权协议那样,该协议最大的风险不在于其协议本身,而是它周边的应用程序。



目录(Table of Contents)

1 访问鉴别(Access Authentication)..................... ..................... ................................   3

1.1 对HTTP/1.1规范的依赖(Reliance on the HTTP/1.1 Specification)............   3

1.2 访问鉴别框架(Access Authentication Framework)................. .....................   3

2 基本鉴别方案(Basic Authentication Scheme)........................ ............... ...............     5

3 分类访问鉴别方案(Digest Access Authentication Scheme)............. .....................   6

3.1 介绍(Introduction)................................. ..................... ..................... ......... 6

3.1.1 目的(Purpose)...................................... ..................... .......................   6

3.1.2 操作概述(Overall Operation)........................ ..................... ... ......... 6

3.1.3 分类值表示(Representation of digest values)............ ......................     7

3.1.4 局限性(Limitations)................................... ..................... .................     7

3.2 分类标题规范(Specification of Digest Headers)................. ..................…..     7

      3.2.1 WWW-鉴别回应标题(The WWW-Authenticate Response Header)..     8

3.2.2 授权请求标题(The Authorization Request Header)....... ...................     11

3.2.3 鉴别信息标题(The Authentication-Info Header)....... ...................….     15

3.3   分类操作(Digest Operation)........................... ..................... .....................     17

3.4   安全协议商议(Security Protocol Negotiation).. ........................................     18

3.5   例子(Example)...................................... ..................... ..................... ......….     18

3.6   代理鉴别和代理授权(Proxy-Authentication and Proxy-Authorization).... 19

4 安全考虑(Security Considerations)............................ ..................... ...................…..     19

4.1 使用基本鉴别方式的客户端鉴别(Authentication of Clients using Basic

      Authentication).............................. ..................... ..................... .....................     19

4.2 使用分类鉴别方式的客户端鉴别(Authentication of Clients using Digest

      Authentication).............................. ..................... ..................... .....................     20

4.3 使用有限制的nonce值(Limited Use Nonce Values)..................... ..............     21

4.4     用基本鉴别方式来进行分类比较(Comparison

of Digest with Basic Authentication).. ..................... ..................... ..............     22

4.5 攻击回放(Replay Attacks).............................. ..................... ........................     22

4.5     由多方鉴别方案产生的弱点(Weakness

Created by Multiple Authentication Schemes).................................. ............     23

4.7 在线字典攻击(Online dictionary attacks)...................... ..................... .......     23

4.8 中间人(Man in the Middle).............................. ..................... .....................     24

4.9 选择纯文本攻击(Chosen plaintext attacks)............... ..................... ............     24

4.10 用预先计算的字典攻击(Precomputed dictionary attacks)............... ..........     25

4.11 批方式暴力攻击(Batch brute force attacks)...................... ........ .............. 25

4.12 假冒服务器欺骗(Spoofing by Counterfeit Servers)............... ...................   25

4.13 存储口令(Storing passwords)........................ ..................... .....................     26

4.14 摘要(Summary)................................ ..................... ..................... .............     26

5 例子实现(Sample implementation)....................... ..................... ..........................   27

6 感谢(Acknowledgments).............................. ..................... ..................... .. ............. 31

Franks, et al.         Standards Track               [Page 2]


7 参考书目(References)....................................... ..................... .............. ................     31

8 作者地址(Authors' Addresses)............................ ..................... ............................     32

9 完整版权状况(Full Copyright Statement)........................ ..................... ..................   34


RFC2617- HTTP Authentication自译本-(2)


1 授权鉴别(Access Authentication)

1.1对HTTP/1.1规范的依赖(Reliance on the HTTP/1.1 Specification)

    本规范和HTTP/1.1规范[2]一起使用,它使用HTTP/1.1文档2.1节的补充反馈方式(Augmented BNF),并依赖于该文档对非终端(non-terminals)的定义及对其它方面的描述。


1.2 访问鉴别框架(Access Authentication Framework)

    HTTP提供了简单的挑战-回应鉴别机制,它可能被服务器用来质询客户端请求,也可能被客户端用来提供鉴别信息。授权方案用可扩展的、大小写敏感的符号来标识,后跟获取证明所需要的以逗号分隔的‘属性-值’对。
auth-scheme   = token

auth-param   = token "=" ( token | quoted-string )

    401(未授权)回应消息被原始服务器端用来质询用户代理的授权。该回应必须包括含有至少一个被请求资源质询(challenge)的WWW-鉴别标题域。407(需要鉴别代理)回应消息被代理用来质询客户端的授权,它的代理鉴别标题域(Proxy-Authenticate header field)必须包括至少一个代理方(proxy)对被请求资源的质询。

challenge   = auth-scheme 1*SP 1#auth-param

    注意:用户代理(agent)解析WWW-鉴别(WWW-Authenticate)或代理-鉴别(Proxy-Authenticate)的标题域,在碰到含有多个质询()或多个WWW-鉴别标题域时,要特别小心,因为这些质询本身可能就包含了以逗号分隔的鉴别参数对。

    鉴别参数realm的定义在所有的鉴别方案中使用:

realm         = "realm" "=" realm-value

realm-value     = quoted-string

Franks, et al.         Standards Track               [Page 3]

    Realm指示(大小写敏感)在所有涉及质询(challenge)的鉴别方案中都要用到。Realm值(大小写敏感)要与被访问服务器的‘根’URL的规范用法(即绝对路径为空的服务器的绝对URI-absoluteURI,见5.1.2节[2])联合使用,以定义受保护的区间。这些realm参数允许将服务器上受保护资源分成若干个区间,每个区间都有其自己的鉴别方案和(或)授权数据库。Realm值是字符串,通常由原始服务器分配,针对某些鉴别方案可能还有附加的语法问题。注意,可能存在多个质询(challenge),auth-scheme相同,而realm不同的情况。


通常,用户代理(agent)在收到401(未授权)回应时,可能(也可能不会)希望服务器对其授权。如果希望授权,用户代理将在请求中加入授权请求标题(Authorization request-header)域。授权域值由信任证书组成,其中有对用户代理所请求资源领域的授权信息。客户端在收到407(需要代理鉴别)回应时,如希望通过代理进行自身的鉴别,可在请求中加入代理授权请求标题域(Proxy-Authorization request-header)。授权域值和代理授权域值都是由信任组成,这些信任包括被请求资源的客户端鉴别信息realm的值。用户代理(user agent)必须选用它所能理解的最强的auth-scheme及用户回应质询(challenge)的请求信任。

credentials = auth-scheme #auth-param

    注意,许多浏览器只支持基本方案,要求它在auth-scheme中排在第一位。如果提供最低程度的满意度,服务器端应只支持基本方案。

    受保护区间定义了将要自动使用信任的区域。如果早先的请求已经通过认证,在由授权方案,参数和(或)用户选择等所指定的时间间隔内,其它的请求可通过相同的信任来访问该保护区域。除非鉴别方案有特别指定,否则单个保护区域不能扩展到该服务器以外的范围。

    如果原始服务器不希望通过发送的请求来接受信任,它应当返回401(未授权)回应。该回应必须包括一个WWW-鉴别标题域,而该域要包含至少一个(可能是新的)对被请求资源的质询(challenge)。如果代理(proxy)不接受用请求方式发送信任,它应当返回407(需要代理鉴别)回应。该回应必须包括一个代理鉴别(Proxy-Authenticate)标题域,而该域要包含至少一个(可能是新的),代理可用的,对被请求资源的质询。





























Franks, et al.         Standards Track               [Page 4]




HTTP协议的访问鉴别并不限于这种简单的质询回应(challenge-response)机制,还可以使用其它的方法,比如传输级加密或消息封装及通过附加标题域来指定鉴别信息等等。但是,这些方法不在本文档的讨论范围。



    代理(proxy)必须完全透明地处理原始服务器对用户代理(user agent)的鉴别,也就是说,它们必须在不做任何改动的前提下将WWW-鉴别和授权标题向前推送,这方面的规定见[2]的14.8节。代理-鉴别(WWW-Authenticate)和代理-授权(Proxy-Authorization)标题域都是hop-by-hop标题(见[2]的13.5.1节)。





2 基本鉴别方案(Basic Authentication Scheme)



用户代理必须对于每个领域(realm)通过用户标识(user-ID)及口令来对自身进行授权,这是基本授权方案的工作模式。Realm值应当被看作不透明的字符串,该值将用于同服务器端其它的realm值相比较。只有用户标识及口令通过受保护资源的认证,服务器才会给请求授权。授权参数没有可选项。



    对于基本方案,上面所述框架的应用形式如下:



challenge       = "Basic" realm

credentials     = "Basic" basic-credentials



在接收到对受保护区域的未经认证的资源请求时,服务器应当回应一个质询(challenge),如下:



WWW-Authenticate: Basic realm="WallyWorld"



    “WallyWorld”是由服务器分配的字符串,用于对请求URI所指定的受保护资源进行标识。代理也应使用使用Proxy-Authenticate标题域来回应同样的质询。



    为了接收授权,客户端需要在基于64位(base64 [5])的证书中发送用户标识及口令,中间用冒号’:’分隔。



basic-credentials           = base64-user-pass

base64-user-pass         = <base64 [4] encoding of user-pass,

                            except not limited to 76 char/line>







Franks, et al.         Standards Track               [Page 5]


user-pass       = userid ":" password

userid         = *<TEXT excluding ":">

password       = *TEXT



    Userids可能是大小写敏感的。



如果用户代理希望发送用户标识”Aladdin”和口令“open sesame”,应当遵循下面的标题域形式:



    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==



    客户端应当假定请求URI中所涉及的所有其它路径都在由当前质询的基本realm值所指定的保护空间中。客户端在未收到服务器的其它质询时,可能会优先发送对应于该空间资源的授权标题。同样,当客户向代理(proxy)发送请求,它也可能在未收到代理服务器的其它质询之前,在代理授权(Proxy-Authorization)标题域中还使用原来的uerid和password。详情参见[安全考虑]的第4节中与基本鉴别相关的内容。



3 分类访问鉴别方案(Digest Access Authentication Scheme)



3.1 介绍(Introduction)



3.1.1 目的(Purpose)



   

    “HTTP/1.0”中包括基本访问鉴别方案(Basic Access Authentication scheme[1])。该方案不是安全的用户鉴别方法,因为其用户名和口令在网络上是以明文方式传送的。本节提供不以明文方式发送口令的方案规范,参见”分类访问鉴别”。



    分类访问鉴别(Digest Access Authentication)方案不是WWW安全问题的最终解决方案。该方案不提供消息内容的加密,其目的只是创建一个简单的鉴别方法,以弥补基本鉴别方案中存在的大部分严重漏洞。



3.1.2 操作概述(Overall Operation)



    和基本访问鉴别相似,分类方案基于简单的挑战-回应范例。分类方案使用nonce值来质询(challenge)。合法的回应包含对用户名、口令、给定nonce值、HTTP方法、请求URI的校验和(checksum,缺省是MD5的校验和),因此,口令不会以明文方式传送。有些基本方案要求将用户名及口令预先排成一定的格式(不在本文范围)后再行使用。











Franks, et al.         Standards Track               [Page 6]




3.1.3 分类值的表示(Representation of digest values)



    可选的标题,允许服务器指定用来创建校验和或分类的算法。MD5是缺省的方法,而且也是本文唯一提及的算法。



    在本文中,128位的MD5分类由32个可打印的ASCII码字符表示。128位分类中的位按其重要性由高到低转换,在某个时刻每4位可用下面的ASCII表示。每4位都可用16进制字符‘0123456789abcdef’表示,也就是说,二进制0000由字符‘0’表示;0001由字符‘1’表示,以后如此类推,1111用‘f’表示。



3.1.4 局限性(Limitations)



    本文中描述的分类鉴别方案存在许多已知的局限性,它只是对基本鉴别方案的替代,除此外,别无他用。它是基于口令认证的系统,在服务器端也要面对任何其它口令系统同样存在的问题。本协议并没有为最初用户和服务器间的口令建立提供安全做法。

   

    用户和开发者都应注意,该协议并不象Kerberos或任何客户端的私钥方案那样安全。但是,即便它一无是处,总还比在telnet、ftp用的机制好一些,当然,也比基本方案安全。



3.2 分类标题的规范(Specification of Digest Headers)



    分类访问鉴别方案在概念上与基本方案相似。更改的WWW-鉴别标题行和授权标题行的格式在下面给出。另外,还有个新的标题,即Authentication-Info,也在下面指定。









































Franks, et al.         Standards Track               [Page 7]




3.2.1 WWW-鉴别回应标题(The WWW-Authenticate Response Header)



    服务器在收到对受保护对象未经认证的访问请求时,会回应401(未授权)状态码。在分类方案中,WWW-鉴别标题应遵循如下写法:



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

显示给用户看的字符串,这样他们就知道使用哪个用户名和口令了。该字符串应当包括至少一个执行鉴别的主机名和对可能访问用户群体的附加指示。例如:



registered_users@gotham.news.com



domain

指在引号中用空格分隔的URI列表(见RFC XURI[7]中定义的保护区间)。如果URI是采用绝对路径,它是相对于被访问服务器‘根’的URL(见上面1.2节)。该列表中的绝对URI被用来访问另外一个不同的服务器。客户端可发送同样的鉴别信息来访问由此列表确定的URI集合:任何URI,只要其做为前缀出现在列表中,就可以认为它指向同样的受保护区域。如果表示被忽略或是空值,客户端应这样理解,即,该保护区域由回应服务器的全部URI组成。











Franks, et al.         Standards Track               [Page 8]




该表示对代理-鉴别(Proxy-Authenticate)标题没有意义,因为对它们来说,受保护区域总是整个代理(proxy),如果出现,也会被忽略。



nonce

服务器端指定的数据字符,它应在每个401回应产生时,被唯一地创建。建议该字符以base64方式或16进制方式出现。另外,该字符在标题行中传递时是在引号内的,因此允许使用双引号字符。

其内容与实现无关,而其实现的质量取决于良好的选择。例如,nonce可能以基于64位编码来构造,如下例:



time-stamp H(time-stamp ":" ETag ":" private-key)



如上,时间戳(time-stamp)是由服务器产生的时间值或其它非重复值;Etag是HTTP 与请求实体相关的ETag标题的值;private-key是只有服务器才知道的值。在碰到这种形式的nonce时,服务器在收到客户鉴别标题后,会对哈希部分进行重新计算,并在nonce值与标题不符或其time-stamp值不够新时拒绝该请求。通过这种方式,服务器端可以限制nonce合法的时间范围。Etag中的内容将防止对资源的更新版本进行重复请求。(注意:在nonce中包括客户端的IP地址将向服务器提出要求,即不要再重用同样客户发出的nonce值。实际上,单个用户发出的请求会穿越多个代理,这样做可能导致该过程的中断。另外,IP地址也是可以假冒的)



有的实现可能会选择不接受先前先用的nonce或先前使用的分类,以防止回放式攻击(replay attack)。或者,实现在回应POST|PUT请求时,也可以选择以前的nonce或分类(digest)和GET请求的time-stamp。更详细的信息,见本文第4节。



nonce是客户端的opaque。



opaque

由服务器指定的字符串,客户端不能改动它,如果并发请求的URI也指向同一个受保护区间,则该信息将被加在这些请求的授权标题域中返给服务器。建议采用base64或16进制的字符串。

   























Franks, et al.         Standards Track               [Page 9]




stale

一个标志,用来指示客户端先前的请求因其nonce值过期而被拒绝。如果stale是TRUE(大小写敏感),客户端可能希望用新的加密回应重新进行请求,而不用麻烦用户提供新的用户名和口令。服务器端只有在收到的请求nonce值不合法,而该nonce对应的分类(digest)是合法的情况下(即客户端知道正确的用户名/口令),才能将stale置成TRUE值。如果stale是FALSE或其它非TRUE值,或者其stale域不存在,说明用户名、口令非法,要求输入新的值。



algorithm

是个字符串,用来指示用来产生分类及校验和的算法对。如果该域没指定,则认为是“MD5“算法。如果该域指定的算法无法理解,该质询(challenge)将被忽略。

   

在本文中,用KD(secret,data)来表示分类算法,其中data指数据,secret表示采用的方法.如果表示校验和算法时,data要写成H(data);而unq(X)表示将带引号字符串的引号去掉。

   

        对于"MD5" 和"MD5-sess" 算法:



H(data) = MD5(data)





KD(secret, data) = H(concat(secret, ":", data))

也就是说,分类(digest)就是对secret与data通过冒号连接一起的结果进行MD5运算。而"MD5-sess"算法则允许其它第三方服务器参与鉴别。具体用法的区别,参见3.2.2.2节的描述。



qop-options

该表示是可选的,用于RFC2069[6]的向后兼容。它应当被与该分类方案版本兼容的任何实现所使用。如果存在,它是带引号的一个或多个字符组成的字符串,用来指示服务器支持的保护水平(quality of protection)值。”auth”值表示鉴别方式;”auth-int”表示鉴别保护的完整性;见后面为有该项选择的应用程序重新计算回应指示值。不能识别的选项必须被忽略。


Franks, et al.         Standards Track             [Page 10]      



RFC2617- HTTP Authentication自译本-(3)



auth-param

      该指示用于未来扩展。任何无法识别的指示都必须被忽略。



3.2.2 授权请求标题(The Authorization Request Header)



    客户端想重试发送请求,并传递对应前面所框架定义的授权标题行,如下:



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   ; As specified by HTTP/1.1

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"



    opaque域和算法(algorithm)域的值必须在被请求实体的WWW-鉴别回应标题中给出。



response

    是个字符串,由32个经过计算的16进制数字组成,用来证明用户是否知道口令。



username

      用户名,是指定的realm项。















Franks, et al.         Standards Track             [Page 11]




digest-uri

从请求队列(Request-Line)中的请求URI得到的URI;这里存在副本是因为代理(proxy)在传送时允许对请求队列进行修改。



qop

指示客户端对该消息应用的保护等级(quality of protection)。如果不为空,其值必须是服务器支持在WWW-鉴别标题中采用的几种值之一。这些值会对请求-分类(request-digest)的计算造成影响。注意,这是个单独的符号,而不是象WWW-鉴别(WWW- Authenticate)那样,是带引号的可选值列表。该指示是可选项,这是为了和RFC2069[6]所规定的最小实现保持向后的兼容性。但是,如果服务器端通过在WWW-鉴别(WWW- Authenticate)标题域中添加qop指示,就表明该服务器支持qop,因而,必须使用该项指示。



cnonce

当qop指示发送了(见上面),该指示必须要指定,而当服务器端没有在WWW-鉴别(WWW- Authenticate)标题域中添加qop指示时,该指示一定不能指定。cnonce-value是客户端提供的字符串,它由客户端和服务器共同使用,用来避免选择纯文本攻击、提供共同鉴别、提供某些消息的完整性保护。详情见下面的回应分类(response-digest)值和请求-分类(request-digest)值的计算。



nonce-count

当qop指示发送了(见上面),该指示必须要指定,而当服务器端没有在WWW-鉴别(WWW- Authenticate)标题域中添加qop指示时,该指示一定不能指定。nc-value是16进制表示的计数值,用来统计客户端发送的带nonce值的请求(包括当前请求)个数。例如,在第一个请求回应中给出了nonce的值,客户端发送”nc=00000001",其目的是允许服务器通过对此计算副本的维护来检测请求重复(request replay),即当同样的nc-value出现两次,说明请求是可回放的。详情见下面请求-分类(request-digest)值的构建。



auth-param

该指示用于未来扩展。任何无法识别的指示都应被忽略。



    如果指示或其值不正确,或者需要的指示没有给出,都会得到400(非法请求)回应。如果请求-分类(request-digest)是非法的,登录失败将会被记入日志,因为在某个单独的客户端出现的重复登录失败可能意味着攻击者正试图猜测口令。

















Franks, et al.         Standards Track             [Page 12]
    前面定义的请求-分类(request-digest)指示了其编码方式。下面的定义将表明这些值是如何参与计算的。



3.2.2.1 请求-分类(Request-Digest)



    如果”qop”值是"auth" 或"auth-int":



request-digest = <"> < KD ( H(A1),     unq(nonce-value)

                          ":" nc-value

                          ":" unq(cnonce-value)

                          ":" unq(qop-value)

                          ":" H(A2)

                      ) <">



    如果”qop”指示没有给出(与RFC2069保持兼容性):



request-digest =<"> < KD ( H(A1),     unq(nonce-value)

":" H(A2)

) <">



    A1及A2的定义在下面。



3.2.2.2 A1



    如果算法("algorithm")值是”MD5”或没有指定,则A1是:



A1     = unq(username-value) ":" unq(realm-value) ":" passwd



其中



passwd   = < user's password >



    如果"algorithm"值是"MD5-sess",则A1只要计算一次,即当客户端发出第一个请求,并从服务器收到WWW-鉴别(WWW-Authenticate)质询(challenge)时计算。它使用该质询中的服务器的nonce,则用来构建A1的第一个客户端nonce值应为:



A1       = H( unq(username-value) ":" unq(realm-value)

              ":" passwd )

              ":" unq(nonce-value) ":" unq(cnonce-value)

    上式为并发请求和回应的鉴别产生一个‘会话密钥’(session key),该密钥对于每个‘鉴别会话’(authentication session)都是不同的,这样,就限制了使用任何一个密钥进行哈希处理的次数(注意:鉴别会话更深层次的探讨见3.3节)。





Franks, et al.         Standards Track             [Page 13]




因为服务器只需要使用用户信任的哈希值来产生A1值,因而该机制可允许第三方参与鉴别服务,这样WEB服务器就不再需要实际的口令值了。该协议的规范已经超出了本规范的内容范围。



3.2.2.3 A2



    如果”qop”值是”auth”或者没给出,则A2:



A2     = Method ":" digest-uri-value



如果"qop"值是"auth-int", 则A2:



A2     = Method ":" digest-uri-value ":" H(entity-body)



3.2.2.4 指示值和带引号的字符串(Directive values and quoted-string)



    注意,许多指示的取值,如”username-value”等,被定义成带引号的字符串(quoted-string)。而实际上,”unq”注释则表示在生成字符串A1时,去掉其外部的引号。因而,如当授权标题包括该域,如:



username="Mufasa", realm=myhost@testrealm.com

    则表示用户Mufasa的口令是"Circle Of Life",这样H(A1)就可表示成

H(Mufasa:myhost@testrealm.com:Circle Of Life),注意,在分类字符串中没有引号。

    注意,在分类函数H()中的字符串中不允许出现空格,除非空格出现在带引号的字符串内或者用以标记字符串分类的实体主体中。例如,上面出现的字符串A1必须是



Mufasa:myhost@testrealm.com:Circle Of Life



    在冒号的两边都不可以有空格,但是允许口令单词之间出现空格(Circle+SP+Of+SP+Life)。同样,其它由H()分类的字符串也不能在用于域间分隔的冒号两边加空格,除非空格在引号内或被分类的实体主体内。



    同样要注意的是,如果应用了完整性保护(integrity protection),即qop=auth-int,则H(实体-主体)就是实体主体的哈希值,而不是消息主体的哈希值,该值在发送方进行任何传输编码前计算,之后,被接收方删除。

















Franks, et al.         Standards Track             [Page 14]




    注意,它在任何多部分内容-类型(multipart content-type)中的每个部分都包括多部分的边界和嵌入标题。



3.2.2.5 多样性考虑(Various considerations)



    "Method"(方法)值是指HTTP请求的方法,见[2]的5.1.1节。"request-uri"值请求队列中指定的请求URI,见[2]的5.1.2节。可能还会有”*”号,即绝对URL("absoluteURL" 或 "abs_path"),见[2]的5.1.2节,但必须与请求URI保持一致。特殊情况,当请求URI是绝对URL时,它也必须是绝对URL形式。"cnonce-value"是客户端可选的值,用来防止纯文本攻击。

    进行鉴别的服务器必须保证"uri"所指向的资源与请求队列中指定的资源相同;如果不同,服务器应当回应400(非法请求)消息。注意,由于这可能是攻击的前兆,服务端的实现可能要对此进行日志记录。



在该域的请求URL中包含重复信息的目的是因为中间的代理服务器可能会更改客户端的请求队列。已经更改的请求(尽管可以恢复原状)将会导致由客户端计算的分类发生变更。



    开发者应当注意己鉴别的事务是如何与共享缓存进行交互的。HTTP/1.1协议规定,如果共享缓存(见[2]的13.7)收到的请求中所包含的授权标题和回应是由请求中继传来的,此时一定不能将该回应做为对其它请求的回答,除非是回应中包括两种缓存-控制(Cache-Control)指示中的任何一种才可以。



如果原始服务器回应中指明"must-revalidate"(必须重新授权)的缓存控制指示,缓存虽然可以在回应并发请求时使用该回应的实体,但必须先从原始服务器处得到认可才行,认可的方法是用新请求的请求标题到原始服务器处获取授权。同样,如果原始服务器回应中包括”public”缓存控制指示,则对任何并发请求都可应用此回应的实体。



3.2.3 鉴别信息标题(The Authentication-Info Header)



    Authentication-Info标题被服务器用做通讯区,以得到回应中鉴别成功的一些信息。



























Franks, et al.         Standards Track             [Page 15]




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 <">



nextnonce值是服务器希望客户端在未来鉴别回应中采用的nonce值。服务器可能发送带有nextnonce域的Authentication-Info标题,以实现一次性或可变的鉴别方式。如果nextnonce域有值,客户端应当在下次请求中使用该值来构建授权标题。如果有"stale=TRUE"存在,客户端的失败将导致服务器端对请求进行重新鉴别。

服务器的实现应当小心处理采用这种机制而引发的潜在性能问题;如果每个请求都包括由服务器指定的、必须在下个请求时使用的nextnonce值,那么管道式(pipelined)请求不可能实现。要想实现管理式请求,而且要顾及性能和安全性的平衡,可在一段有限时间内, 允许使用旧的nonce值。使用nonce-count可以在不危害管道的前提下,保留新服务器nonce的大多数安全特性。



message-qop



表示用于服务器回应的保护等级选项。"auth"值表示鉴别;而"auth-int"值则表示采用完整性保护的鉴别。服务器在回应客户端请求时,应当采用和message-qop相同的值。



        在"response-auth"中的可选回应分类支持相互鉴别,即服务器可以证实它知道用户的秘密,也可通过qop=auth-int对回应提供有限的完整性保护。"response-digest"值用于授权标题中的"request-digest"值的计算,除非指定请求的授权标题中包含"qop=auth"或没指定,则A2是:



A2       = ":" digest-uri-value



若包含"qop=auth-int", 则A2 是:



A2       = ":" digest-uri-value ":" H(entity-body)





















Franks, et al.         Standards Track             [Page 16]




    其中,"digest-uri-value"是请求中授权标题所指向的"uri"。而"cnonce-value"和"nc-   value"必须做为客户端请求的回应消息的组成部分。当指定了"qop=auth"或"qop=auth-int"时,"response-auth"、"cnonce"、和"nonce-count"必须给出。



    Authentication-Info标题允许对通过块编码(chunked transfer-coding)传输的HTTP消息进行追踪。



3.3 分类操作(Digest Operation)

   

    在接收授权标题前,服务器可能要先检查对应用户名、口令的合法性。这时,服务器必须执行和客户端相同的分类操作(如,MD5),并将结果与给定请求-分类(request-digest)相比较。



    注意,HTTP服务器只要支持H(A1),就不必知道用户的口令明文,而授权标题的合法性照样可以鉴别。

   

    客户端在回应对受保护区间的WWW-鉴别(WWW-Authenticate)质询时,启动同该受保护区间之间的鉴别会话。鉴别会话在客户端收到受保护区中的任何服务器发出的WWW-鉴别(WWW-Authenticate)质询时终止。客户端应当记住与鉴别会话相关的username、password、nonce、nonce count及opaque值,从而能构建将来对指定保护区请求的授权标题。授权标题要被优先包括,这样做会提高服务器效率,并避免鉴别质询可能发生的额外循环。服务器可能选择接受旧的授权标题信息,即使其中包含的nonce值已过期。同样,服务器可能回应401,其中包括了新的nonce值,这样会引起客户端重试该请求;通过在回应中指定stale=TRUE,服务器通知客户端用新的nonce来重试请求,但是不会再要求输入新的用户名及口令。



    因为客户端在会话期间要把服务器传给它的opaque值返回给服务器,opaque值可用来传递鉴别会话的状态信息。(注意,其实可通过在nonce中包括状态的方法来实现,这样更安全、简单。)例如,服务器要为已经位于其它服务器的鉴别内容负责,其实现是,在第一个401回应中包括domain指示(包括第二个服务器上的URI)和opaque指示(包括状态信息)

























Franks, et al.         Standards Track             [Page 17]






    客户端会在服务器回应301或302(重定向,即,指向第二个服务器上的URI)时重试该请求。客户端会根据重定向信息,传送授权标题,包括<opaque> 数据。



    在基本方案中,代理(proxy)必须完全透明地处理分类访问鉴别方案(Digest access authentication scheme.)。他们必须将WWW-Authenticate、Authentication-Info、和Authorization header向前推送,而不做任何修改。如果代理希望在请求推送到服务器之前对客户进行鉴别,它可以使用代理-鉴别(Proxy-Authenticate)和代理-授权(Proxy-Authorization)标题,见下面3.6节。



3.4 安全协议讨论(Security Protocol Negotiation)



    对服务器来说,了解客户端有能力处理的哪种安全方案是很有用的。

   

    可能存在这种情况,服务器端直接获取分类做为其鉴别方法,而不管客户端是否支持它。如果发生这种情况,服务器指定的鉴别方案恰好是客户端所不支持的,客户端应当明确回应失败。



3.5 例子(Example)



    下面的例子假定通过GET请求来获取服务器上一个带有访问保护的文档。文档的URI是" http://www.nowhere.org/dir/index.html ",客户端和服务器都知道该文档的用户名是"Mufasa",口令是"Circle Of Life"(三个单词间用一个空格分隔)。



    客户端在第一次请求该文档时,没有发送授权标题,于是服务器回应:

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Digest

realm=" testrealm@host.com ",

qop="auth,auth-int",

nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",

opaque="5ccc069c403ebaf9f0171e9517f40e41"



    客户端可能会在新的请求中提供用户名和口令,包括下面的授权标题:



















Franks, et al.         Standards Track             [Page 18]




Authorization: Digest username="Mufasa",

realm=" testrealm@host.com ",

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标题,分类鉴别方案也可实现在代理、代理间、代理与原始服务器间进行用户鉴别。这些标题是Proxy-Authenticate和Proxy-Authorization标题的实例(见HTTP/1.1规范[2],10.33和10.34节,其行为的限制描述)。代理鉴别事务与已经描述的十分相似。在接收需要鉴别的请求之前,代理/服务器必须发出407(需要代理鉴别)回应,其中包含了"Proxy-Authenticate"标题。Proxy-Authenticate标题中使用的分类质询(digest-challenge)与在前面3.2.1节中定义的WWW- Authenticate标题一样。

   

    客户端/代理必须重新发出带有代理授权(Proxy-Authorization)标题的请求,其写法见上面的3.2.2节的授权标题。

   

    在并发回应时,服务器将发送代理鉴别信息(Proxy-Authentication-Info),其写法与Authentication-Info标题域是一样的。

   

    注意,原理上,可要求客户端提供对代理和最终服务器的自身鉴别,但不能在同一个回应当中。



4 安全考虑(Security Considerations)



4.1 用基本鉴别的客户端鉴别(Authentication of Clients using Basic Authentication)



    基本鉴别方案不是安全的用户鉴别方式,也不会对以明文方式在物理网络中传输的实体进行任何形式的保护。HTTP允许使用另外的鉴别方案或加密机制来增强基本协议的安全性能(比如,一次性口令方案)。















Franks, et al.         Standards Track             [Page 19]




    基本鉴别方式最严重的漏洞在于它将用户口令以明文方式在物理网络中传输,而这正是分类鉴别(Digest Authentication)方式试图去解决的。

   

    因为基本鉴别使用了口令的明文传输方式,因此,如果没有使用增强方式,一定不能用来保护敏感或有价值的信息。

   

    基本鉴别方式通常用于识别目的――要求用户提供用户名及口令做为身份标识,例如,用于服务器精确统计使用状况。这种情况看似没有危险,对受保护文件的违法访问不是主要问题。然而,除非由服务器向用户发送用户名、口令,而且不允许用户选择自己的口令时,这种方式才可能安全。否则危险会成倍增加,因为有些天真的用户为避免维护多个口令,而老是使用单个的口令。



    如果服务器允许用户自由选择口令,那带来的危险不仅仅是对服务器文件的未授权访问,而且还会引起对用户用同样口令保护的其它系统资源的未授权访问。此外,在服务器口令数据库中,许多口令同样是用户访问其它站点的口令。因而,如果此类信息不受到安全保护,那么系统的所有者或管理员将会承担因未授权访问而造成的系统用户信息暴露的风险。



    基本鉴别也容易受到假冒服务器欺骗的攻击。当用户坚信他正与一台受基本鉴别方案保护的主机相连时,他也许不会想到,此时他可能正与怀有敌意的服务器或网关相连。攻击者可截获口令,并将其储存起来备用,同时假装返回一个错误。这种类型的攻击在分类鉴别方案下是不可能成功的。服务器端的开发者应当实现对假冒网关或伪装CGI script的防护。在特殊情况下,象服务器打开与某个网关的连接之类看起来很简单的事都有可能产生严重后果,因为这样以后,网关就可扮演成原始服务器,用持久连接的机制同客户建立多种事务交互,而客户可能对此一无所知。



4.2 用分类鉴别的客户端鉴别(Authentication of Clients using Digest Authentication)



    与其它一些安全机制相比,如基于公钥技术的机制,分类鉴别机制要显得脆弱一些。

Franks, et al.         Standards Track             [Page 20]      




RFC2617- HTTP Authentication自译本-(4)




    但它还是比在LDAP[10]、POP及IMAP(见RFC2195[9])上用的CRAM-MD5要强许多。它将被用来替代薄弱的危机四伏的基本机制。

   

    分类鉴别只提供对实际口令的加密保护。请求或回应的所有其它内容都可以被监听。

   

    对双向传递的消息,分类鉴别方案只提供有限的完整性保护。如果使用了qop=auth-int机制,消息中参与计算WWW-鉴别和授权标题域中的回应指示值(见上面的3.2节)的部分将受到保护。大多数标题域及其值都可被修改,从而成为中间层攻击的组成部分。

   

    分类鉴别方案不足以满足许多安全HTTP事务的需要。为此,TLS或SHTTP成为更适合的协议。分类鉴别尤其不能用于许多需要加密保护的事务处理上。尽管如此,许多功能仍得以保留,所以分类鉴别仍然可以继续使用。任何现存的对基本鉴别方案的服务都应根据实际情况尽早转到分类鉴别方案上。



4.3 受限的nonce值使用(Limited Use Nonce Values)



    分类方案使用服务器指定的nonce值为种子生成请求-分类(request-digest)值(见前面3.2.2.1)。如3.2.1节例子所示的nonce,服务器可任意构造它,而它只能用于指定的客户、指定的资源、有限的时间段或使用数量及其它限制。这样做会增强系统保护机制,比如可以抵抗回放式攻击(relay attack,见4.5)。然而,应当看到,选择生成或检测nonce的方法也存在些性能问题及资源消耗。例如,服务器可以通过记录列表检查最近发出的nonce是否返回,并在每个回应的Authentication-Info标题域中发送next-nonce指示,从而实现每个nonce值只能使用一次。这种措施可以抵挡哪怕是立即方式的回放攻击,但是用于检查nonce值的开销也非常高,甚至可能造成管道式请求的鉴别失败(假设返回nonce过期指示)。类似情况,要合并请求指定的元素,如资源的Etag值,也将限制对应版本资源中nonce的使用,从而导致管道失败。因而,此种方案虽然看来有时很有效,但从性能上看,对没采用此方案的一方来说,将是不可接受的。

































Franks, et al.         Standards Track             [Page 21]




4.4 基本鉴别与分类鉴别的比较(Comparison of Digest with Basic Authentication)



    分类鉴别和基本鉴别都是处于安全体系的薄弱端,两者比较的意义在于可在必要时用分类鉴别替代基本鉴别。

   

    事务在网络协议上传输的最大危胁在于网络监听。这些事务可能包含一些与交易相关的数据库在线访问。基本鉴别方案下,偷听者可以得到用户的口令,这样,他就可以在数据库中做任何操作,而且更糟糕的是,该用户使用相同口令保护的一切资源都将受到危胁。

   

    与上面相应,如果采用分类鉴别方案,偷听者最多只能得到事务的访问权而得不到用户口令。偷听者所得到的信息将允许他进行回放式攻击,但只能请求同一个文件,而如果服务器端对nonce的选项进行限制的话,他的请求将不能得逞。



4.5 回放式攻击(Replay Attacks)



    对简单的GET请求而言,对分类鉴别方案实行回放式攻击是没有什么意义的,因为偷听者早已通过回放得到了他所能得到的唯一文件。这是因为被请求文件的URI已经在客户端请求中进行了分类,服务器将只传递这个指定文件。而在基本鉴别方案下则不同,偷听者会得到用户的口令,从而得到受此口令保护的任何文件。

   

    因而,从某种目的上看,防范回放式攻击还是必要的。一个好的分类鉴别的实现可以通过多种方式来解决这个问题。服务器产生nonce值是与实现无关的,但是如果它包含了客户IP、时间戳、资源的Etag及私有服务器密钥(如上面所建议的),将增大回放式攻击的难度。攻击方必须必须让服务器相信请求是来自一个错误的IP地址,从而导致服务器将要发送的文件发到偷听者指定的IP而不是原来的IP地址。 攻击方只有在时间戳过期前才有可能取得成功。对nonce中的客户IP及时间戳进行分类将允许实现程序不必对事务间的状态进行维护。



    对应用程序而言,如果无法容忍可能存在的回放式攻击,可使用时间少于1秒的一次性nonce值。当然,这会增加服务器的额外开销,如,服务器     要记住在nonce时间戳(用来进行分类的)过期前,哪些nonce值已经用过了。不过对于回放式攻击,该方法很有效。

























Franks, et al.         Standards Track             [Page 22]




    实现程序要防范可能存在的、使用POST或PUT请求进行的回放式攻击。如果服务器没有使用一次性或限制性的nonce或(和)用qop=auth-int的完整性保护,攻击方仍然可以通过假冒表格数据(form data)或其它消息主体的方式来构造一个带有合法信任信息的请求,从而成功地实现回放攻击。即使采用完整性保护,标题域中的大多数元数据仍不在保护范围之内。实践中,正确产生nonce,并对提供的保护进行检查,可以有效防范利用先前用过的合法信任来进行的回放式攻击。见4.8。



4.6 由多方鉴别方案产生的弱点(Weakness Created by Multiple Authentication Schemes)



    HTTP/1.1服务器可能在401(鉴别)回应消息中返回多个质询(challenge),每个质询可以使用不同的auth-scheme。用户代理(agent)必须从该质询中选用它所能理解的最强auth-scheme及请求信任。



    注意,许多浏览器只能识别基本鉴别方案,而且要求该方案处于auth-scheme列表中的第一项。服务器如提供最小支持,只应包括基本鉴别方案。

   

    当服务器提供数种使用WWW-Authenticate标题的鉴别方案以供选择时,其安全性与最弱的鉴别方案没有什么不同。参见4.8节使用多种鉴别方案进行精确攻击的讨论内容。



4.7 在线字典攻击(Online dictionary attacks)

   

    如果攻击方可以偷听的话,他可以用常见的单词列表组成nonce/回应对来测试。该列表比起全部可能在口令中出现的单词要少很多。按列表中每一个口令计算回应,并可在每次质询(challenge)时得到回报。



    服务器可以采取措施,不允许用户使用字典中的单词做为口令,这样可以降低这种攻击的危险。

































Franks, et al.         Standards Track             [Page 23]




4.8 中间人(Man in the Middle)



    基本鉴别方案和分类鉴别方案都容易受到‘中间人’(man in the middle,MITM)的攻击。例如,怀有敌意或不安全的代理(proxy)。可以肯定地说,它与所有偷听类问题相关。而且,它还为攻击者提供了一些额外的机会。



    ‘中间人’攻击可能从一组鉴别方案中的薄弱环节入手,并希望客户端使用了已经暴露的用户信任(如口令)。出于这种原因,客户端应尽可能从提供的选项中选择它所支持的最强鉴别方案。

   

    更高级的‘中间人’攻击可能会删除提供的鉴别方案选项,而替换成一个采用基本鉴别方案的质询,这样用户和原始服务器交互的信任将使用明文来传输。还有个更阴险的方法,就是采用‘免费’代理缓存服务来欺骗用户。

   

    当通过鉴别的信任请求被使用时,用户代理(agent)应当考虑其界面显示的尺度,而且应记着当发现服务器要求高级别而回应是低级别时,向用户发出报警信息。另一个不错的主意是,将用户代理配置成分类鉴别方式,或转接到其它安全站点上。另外,有敌意的代理(proxy)还可以伪装成客户端发出请求,当然,和基本鉴别方案相比,还是有一定难度的。



4.9 选择纯文本攻击(Chosen plaintext attacks)



    分类鉴别方案下,‘中间人’或有恶意的服务器可以任意选择客户用来计算回应的nonce值。这种方式被称为‘选择纯文本’攻击。选择已知的nonce可以使密码分析更加容易[8]。

   

    实际上,对采用纯文本进行分类的功能进行单向分析是不可能的。

   

    客户端对抗此攻击的对策是,在配置中要求使用”cnonce”指示;这将允许客户对输入值按照自己的方式而不是攻击者指定的方式进行哈希变换。































Franks, et al.         Standards Track             [Page 24]




4.10 预先计算的字典攻击(Precomputed dictionary attacks)



    分类鉴别方案下,如果攻击方可执行纯文本攻击,攻击方可事先按照常见单词参照nonce的值,计算出一个字典,其中包含回应-口令(response, password)对。这种计算可以在许多机器上并行展开。通过对字典中的口令进行尝试,攻击方可能获得某个质询的回应。虽然字典中的大多数口令可能没有,但是总会有几个成功的。攻击方在挑选质询(challenge),及计算每个口令回应中所付出的代价,终将因许多口令的破译而得到回报。一个含有100万个口令/回应(password/response)对的字典可能要占3.2G的磁盘空间。



    客户端防范此攻击的对策也是使用”connce”指示。



4.11 批方式暴力攻击(Batch brute force attacks)



    在分类鉴别方案下,‘中间人’可以执行纯文本攻击,并从多个用户处收集对应同一个nonce的回应。通过该方法,攻击方可以得到口令集中的能生成有效nonce/response对的全部口令信息。同时,该方法也减少了完全匹配nonce/response对所需要的时间。这种攻击也可在多个机器上同时进行,甚至单机也可进行快速的口令搜索――已有报告证实,6个或6个以下字符组成的密码可在几个小时内破解。



    客户端的对抗策略是使用”cnonce”指示。



4.12 假冒服务器欺骗(Spoofing by Counterfeit Servers)



    基本鉴别方案容易受到假冒服务器攻击。当用户坚信他正与一台受基本鉴别方案保护的主机相连时,他也许不会想到,此时他可能正与怀有敌意的服务器相连。攻击者可截获口令,并将其储存起来备用,同时假装返回一个错误。在分类鉴别方案下,这种攻击实现下来要难一些,但前提是客户端必须要求使用分类鉴别方案,或采用上面提到的一些技术来统计‘中间人’攻击。另外,用户使用的鉴别机制也会在发现这种攻击时给用户提个醒。































Franks, et al.         Standards Track             [Page 25]




4.13 存储口令(Storing passwords)



    分类鉴别方案需要鉴别代理(通常是服务器)将与用户名、口令相关的信息存储到一个由给定的realm参数指定的口令文件中。通过,它包含由用户名和H(A1)组成的对。H(A1)是对用户名、realm、口令进行分类的结果。见上面。

   

    这种机制的隐患在于,一旦口令文件被破解,攻击方就可通过该realm得到本服务器上对指定文档的访问权限。和标准UNIX口令文件不同,不需要对服务器的realm参数进行解密,就可以访问与其相关的文件。另一方面,解密或更确切说是暴力攻击对于获取用户口令是必须的。这就是realm做为分类数据的组成部分存储在口令文件中的原因。这意味着即使一个分类鉴别的口令文件被破译,即用户名和口令己被暴力攻击所破解,也不会危及其它使用相同用户名及口令的文件。

   

    有两个重要结论:

第一,         如果口令文件中包含未加密的口令,则此文件必须受到保护。因为访问文件所需要的许可信息都在realm中,它理当受到看管,事实上这也容易做到。

第二,         任何单独用户使用的realm参数都应当是独一无二的。尤其是realm字符串应当包括进行鉴别操作的主机名。分类鉴别的弱点是客户端无法对服务器进行鉴别。



4.14 摘要(Summary)



    从现代密码字来看,分类鉴别无疑很脆弱。但从一定范围上看,它在取代基本鉴别方面还是有一定价值的,它能从一定程度(不是全部)上补救基本鉴别方案的不足。分类鉴别方案的强壮程度取决于其实际的实现方式。特别是,依赖服务器实现的nonce结构更易受到回放式攻击,对此,大多数服务器提供的选项还是恰当的,如由服务器方来承担使用一次性nonce或分类的开销来防范可能的回放式攻击。另外,还可对nonce中的信息进行限制,如限制单一的IP地址、单一的Etag或限制nonce的寿命周期等等,来满足安全方面的需求。































Franks, et al.         Standards Track             [Page 26]




    密码安全的极限,或说底线(bottom line)是:任何(*any*)己实现的应用与密码标准相比都要稍弱一些,但是任何(*any*)己实现的应用都远比基本鉴别方案高级。



5 例子实现(Sample implementation)



    下面的代码实现了了计算请求-分类(request-digest)和回应-分类(response-digest)的H(A1)、H(A2),还将提供一个测试程序以用来计算3.5节中例子所用到的值。它使用MD5实现(RFC1321)。



File "digcalc.h":

#define HASHLEN 16

typedef char HASH[HASHLEN];

#define HASHHEXLEN 32

typedef char HASHHEX[HASHHEXLEN+1];

#define IN

#define OUT

/* 计算每个HTTP分类H(A1)值,即calculate H(A1) as per HTTP Digest spec*/

void DigestCalcHA1(

  IN char * pszAlg,               //计算方式:md5-sess或md5

  IN char * pszUserName,          //用户名

  IN char * pszRealm,             //realm

  IN char * pszPassword,         //口令

  IN char * pszNonce,             //nonce

  IN char * pszCNonce,           //cnonce

  OUT HASHHEX SessionKey   //会话密钥

  );

/* 计算每个HTTP分类的请求-分类/回应-分类值,即

calculate request-digest/response-digest as per HTTP Digest spec */

void DigestCalcResponse(

  IN HASHHEX HA1,               /* H(A1) */

  IN char * pszNonce,             /*nonce from server(来自服务器的nonce)*/

  IN char * pszNonceCount,         /* 8 hex digits(八个16进制数字)*/

  IN char * pszCNonce,           /* client nonce(客户端的nonce)*/

  IN char * pszQop,               /* qop-value(qop值): "", "auth", "auth-int" */

  IN char * pszMethod,           /* method from the request(请求方法)*/

  IN char * pszDigestUri,     /* requested URL(请求URL)*/

  IN HASHHEX HEntity,           /* H(entity body) if qop="auth-int" */

  OUT HASHHEX Response   /* request-digest or response-digest */

  );

File "digcalc.c":

#include <global.h>

#include <md5.h>



Franks, et al.         Standards Track             [Page 27]




#include <string.h>

#include "digcalc.h"

/*将二进制转换成16进制*/

void CvtHex(     IN HASH Bin,

            OUT HASHHEX Hex)

{

unsigned short i;

unsigned char j;

for (i = 0; i < HASHLEN; i++)

{

j = (Bin[i] >> 4) & 0xf;

if (j <= 9)         Hex[i*2] = (j + '0');

else         Hex[i*2] = (j + 'a' - 10);

j = Bin[i] & 0xf;

if (j <= 9)         Hex[i*2+1] = (j + '0');

else           Hex[i*2+1] = (j + 'a' - 10);

};

Hex[HASHHEXLEN] = '\0';

};

/* 计算H(A1),calculate H(A1) as per spec */

void DigestCalcHA1(

IN char * pszAlg,                 //计算方式:md5-sess或md5

IN char * pszUserName,           //用户名

IN char * pszRealm,           //realm

IN char * pszPassword,             //口令

IN char * pszNonce,           //nonce

IN char * pszCNonce,           //cnonce

OUT HASHHEX SessionKey       //会话密钥

)

{

MD5_CTX Md5Ctx;

HASH HA1;



MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));

MD5Final(HA1, &Md5Ctx);

if (stricmp(pszAlg, "md5-sess") == 0) {



Franks, et al.         Standards Track             [Page 28]


MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, HA1, HASHLEN);

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));

MD5Final(HA1, &Md5Ctx);

};

CvtHex(HA1, SessionKey);

};

/*计算每个HTTP所指定的request-digest/response-digest */

void DigestCalcResponse(

IN HASHHEX HA1,         /* H(A1) */

IN char * pszNonce,         /* nonce from server */

IN char * pszNonceCount,   /* 8 hex digits */

IN char * pszCNonce,       /* client nonce */

IN char * pszQop,           /* qop-value: "", "auth", "auth-int" */

IN char * pszMethod,       /* method from the request */

IN char * pszDigestUri,       /* requested URL */

IN HASHHEX HEntity,       /* H(entity body) if qop="auth-int" */

OUT HASHHEX Response /* request-digest or response-digest */

)

{

MD5_CTX Md5Ctx;

HASH HA2;

HASH RespHash;

HASHHEX HA2Hex;

// calculate H(A2)

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));

if (stricmp(pszQop, "auth-int") == 0) {

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);

};

MD5Final(HA2, &Md5Ctx);

CvtHex(HA2, HA2Hex);

// calculate response

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, HA1, HASHHEXLEN);

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));

MD5Update(&Md5Ctx, ":", 1);

if (*pszQop) {

Franks, et al.         Standards Track             [Page 29]

MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));

MD5Update(&Md5Ctx, ":", 1);

MD5Update(&Md5Ctx, pszQop, strlen(pszQop));

MD5Update(&Md5Ctx, ":", 1);

};

MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);

MD5Final(RespHash, &Md5Ctx);

CvtHex(RespHash, Response);

};

File "digtest.c":



#include <stdio.h>

#include "digcalc.h"



void main(int argc, char ** argv) {

char * pszNonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093";

char * pszCNonce = "0a4f113b";

char * pszUser = "Mufasa";

char * pszRealm = " testrealm@host.com ";

char * pszPass = "Circle Of Life";

char * pszAlg = "md5";

char szNonceCount[9] = "00000001";

char * pszMethod = "GET";

char * pszQop = "auth";

char * pszURI = "/dir/index.html";



HASHHEX HA1;

HASHHEX HA2 = "";

HASHHEX Response;



DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,pszCNonce, HA1);

DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,

pszMethod, pszURI, HA2, Response);



printf("Response = %s\n", Response);

};

Franks, et al.         Standards Track             [Page 30]      

     

RFC2617- HTTP Authentication自译本-(5)全文完


6 感谢(Acknowledgments)

AbiSource公司的Eric W. Sink是本规范修订以前版本的原始作者。



通过讨论方式对本规范做出贡献的其它作者有:

Peter J. Churchyard、Ned Freed和David M. Kristol。



    Jim Gettys和Larry Masinter对本文档做了最后更新。



7 参考书目(References)

  [1] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext

    Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.



  [2] Fielding, R., Gettys, J., Mogul, J., Frysyk, H., Masinter, L.,

    Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol --

    HTTP/1.1", RFC 2616, June 1999.



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

    1992.



  [4] Freed, N. and N. Borenstein. "Multipurpose Internet Mail

    Extensions (MIME) Part One: Format of Internet Message Bodies",

    RFC 2045, November 1996.



  [5] Dierks, T. and C. Allen "The TLS Protocol, Version 1.0", RFC

    2246, January 1999.



  [6] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,

    Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP :

    Digest Access Authentication", RFC 2069, January 1997.



  [7] Berners Lee, T, Fielding, R. and L. Masinter, "Uniform Resource

    Identifiers (URI): Generic Syntax", RFC 2396, August 1998.



  [8] Kaliski, B.,Robshaw, M., "Message Authentication with MD5",

    CryptoBytes, Sping 1995, RSA Inc,

    ( http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm )



  [9] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP AUTHorize

    Extension for Simple Challenge/Response", RFC 2195, September

    1997.



  [10] Morgan, B., Alvestrand, H., Hodges, J., Wahl, M.,

    "Authentication Methods for LDAP", Work in Progress.



Franks, et al.         Standards Track             [Page 31]


8 作者地址(Authors' Addresses)



  John Franks

  Professor of Mathematics

  Department of Mathematics

  Northwestern University

  Evanston, IL 60208-2730, USA

  EMail: john@math.nwu.edu



  Phillip M. Hallam-Baker

  Principal Consultant

  Verisign Inc.

  301 Edgewater Place

  Suite 210

  Wakefield MA 01880, USA

  EMail: pbaker@verisign.com



  Jeffery L. Hostetler

  Software Craftsman

  AbiSource, Inc.

  6 Dunlap Court

  Savoy, IL 61874

  EMail: jeff@AbiSource.com



  Scott D. Lawrence

  Agranat Systems, Inc.

  5 Clocktower Place, Suite 400

  Maynard, MA 01754, USA

  EMail: lawrence@agranat.com



  Paul J. Leach

  Microsoft Corporation

  1 Microsoft Way

  Redmond, WA 98052, USA

  EMail: paulle@microsoft.com

















Franks, et al.         Standards Track             [Page 32]


  Ari Luotonen

  Member of Technical Staff

  Netscape Communications Corporation

  501 East Middlefield Road

  Mountain View, CA 94043, USA



  Lawrence C. Stewart

  Open Market, Inc.

  215 First Street

  Cambridge, MA 02142, USA

  EMail: stewart@OpenMarket.com































































Franks, et al.         Standards Track             [Page 33]




9. 完整版权声明(Full Copyright Statement)



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



  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)

   

    由Internet社团提供的RFC作者基金。





Franks, et al.         Standards Track             [Page 34]









译者声明:

    本文档由chifire( chifire@263.net )翻译。

    本文档在排版格式上尽可能保持与原RFC文档的一致。

    由于本人水平有限,可能有些地方译得不够准确,甚至错误,或某些术语翻译有误,还请各位大侠见谅,并来信批评指正。

clq
2005-8-11 21:22:44 发表 编辑

Network Working Group                             J. Franks
Request for Comments: 2617               Northwestern University
Obsoletes: 2069                             P. Hallam-Baker
Category: Standards Track                       Verisign, Inc.
                                        J. Hostetler
                                      AbiSource, Inc.
                                        S. Lawrence
                                  Agranat Systems, Inc.
                                          P. Leach
                                  Microsoft Corporation
                                        A. Luotonen
                        Netscape Communications Corporation
                                        L. Stewart
                                    Open Market, Inc.
                                          June 1999


    HTTP Authentication: Basic and Digest Access Authentication

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.

Copyright Notice

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

Abstract

  "HTTP/1.0", includes the specification for a Basic Access
  Authentication scheme. This scheme is not considered to be a secure
  method of user authentication (unless used in conjunction with some
  external secure system such as SSL [5]), as the user name and
  password are passed over the network as cleartext.

  This document also provides the specification for HTTP's
  authentication framework, the original Basic authentication scheme
  and a scheme based on cryptographic hashes, referred to as "Digest
  Access Authentication". It is therefore also intended to serve as a
  replacement for RFC 2069 [6]. Some optional elements specified by
  RFC 2069 have been removed from this specification due to problems
  found since its publication; other new elements have been added for
  compatibility, those new elements have been made optional, but are
  strongly recommended.



Franks, et al.         Standards Track               [Page 1]

RFC 2617             HTTP Authentication             June 1999


  Like Basic, Digest access authentication verifies that both parties
  to a communication know a shared secret (a password); unlike Basic,
  this verification can be done without sending the password in the
  clear, which is Basic's biggest weakness. As with most other
  authentication protocols, the greatest sources of risks are usually
  found not in the core protocol itself but in policies and procedures
  surrounding its use.

Table of Contents

  1   Access Authentication................................   3
  1.1   Reliance on the HTTP/1.1 Specification............   3
  1.2   Access Authentication Framework...................   3
  2   Basic Authentication Scheme..........................   5
  3   Digest Access Authentication Scheme..................   6
  3.1   Introduction......................................   6
  3.1.1 Purpose.........................................   6
  3.1.2 Overall Operation...............................   6
  3.1.3 Representation of digest values.................   7
  3.1.4 Limitations.....................................   7
  3.2   Specification of Digest Headers...................   7
  3.2.1 The WWW-Authenticate Response Header............   8
  3.2.2 The Authorization Request Header................ 11
  3.2.3 The Authentication-Info Header.................. 15
  3.3   Digest Operation.................................. 17
  3.4   Security Protocol Negotiation..................... 18
  3.5   Example........................................... 18
  3.6   Proxy-Authentication and Proxy-Authorization...... 19
  4   Security Considerations.............................. 19
  4.1   Authentication of Clients using Basic
      Authentication.................................... 19
  4.2   Authentication of Clients using Digest
      Authentication.................................... 20
  4.3   Limited Use Nonce Values.......................... 21
  4.4   Comparison of Digest with Basic Authentication.... 22
  4.5   Replay Attacks.................................... 22
  4.6   Weakness Created by Multiple Authentication
      Schemes........................................... 23
  4.7   Online dictionary attacks......................... 23
  4.8   Man in the Middle................................. 24
  4.9   Chosen plaintext attacks.......................... 24
  4.10 Precomputed dictionary attacks.................... 25
  4.11 Batch brute force attacks......................... 25
  4.12 Spoofing by Counterfeit Servers................... 25
  4.13 Storing passwords................................. 26
  4.14 Summary........................................... 26
  5   Sample implementation................................ 27
  6   Acknowledgments...................................... 31



Franks, et al.         Standards Track               [Page 2]

RFC 2617             HTTP Authentication             June 1999


  7   References........................................... 31
  8   Authors' Addresses................................... 32
  9   Full Copyright Statement............................. 34

1 Access Authentication

1.1 Reliance on the HTTP/1.1 Specification

  This specification is a companion to the HTTP/1.1 specification [2].
  It uses the augmented BNF section 2.1 of that document, and relies on
  both the non-terminals defined in that document and other aspects of
  the HTTP/1.1 specification.

1.2 Access Authentication Framework

  HTTP provides a simple challenge-response authentication mechanism
  that MAY be used by a server to challenge a client request and by a
  client to provide authentication information. It uses an extensible,
  case-insensitive token to identify the authentication scheme,
  followed by a comma-separated list of attribute-value pairs which
  carry the parameters necessary for achieving authentication via that
  scheme.

    auth-scheme   = token
    auth-param   = token "=" ( token | quoted-string )

  The 401 (Unauthorized) response message is used by an origin server
  to challenge the authorization of a user agent. This response MUST
  include a WWW-Authenticate header field containing at least one
  challenge applicable to the requested resource. The 407 (Proxy
  Authentication Required) response message is used by a proxy to
  challenge the authorization of a client and MUST include a Proxy-
  Authenticate header field containing at least one challenge
  applicable to the proxy for the requested resource.

    challenge   = auth-scheme 1*SP 1#auth-param

  Note: User agents will need to take special care in parsing the WWW-
  Authenticate or Proxy-Authenticate header field value if it contains
  more than one challenge, or if more than one WWW-Authenticate header
  field is provided, since the contents of a challenge may itself
  contain a comma-separated list of authentication parameters.

  The authentication parameter realm is defined for all authentication
  schemes:

    realm     = "realm" "=" realm-value
    realm-value = quoted-string



Franks, et al.         Standards Track               [Page 3]

RFC 2617             HTTP Authentication             June 1999


  The realm directive (case-insensitive) is required for all
  authentication schemes that issue a challenge. The realm value
  (case-sensitive), in combination with the canonical root URL (the
  absoluteURI for the server whose abs_path is empty; see section 5.1.2
  of [2]) of the server being accessed, defines the protection space.
  These realms allow the protected resources on a server to be
  partitioned into a set of protection spaces, each with its own
  authentication scheme and/or authorization database. The realm value
  is a string, generally assigned by the origin server, which may have
  additional semantics specific to the authentication scheme. Note that
  there may be multiple challenges with the same auth-scheme but
  different realms.

  A user agent that wishes to authenticate itself with an origin
  server--usually, but not necessarily, after receiving a 401
  (Unauthorized)--MAY do so by including an Authorization header field
  with the request. A client that wishes to authenticate itself with a
  proxy--usually, but not necessarily, after receiving a 407 (Proxy
  Authentication Required)--MAY do so by including a Proxy-
  Authorization header field with the request. Both the Authorization
  field value and the Proxy-Authorization field value consist of
  credentials containing the authentication information of the client
  for the realm of the resource being requested. The user agent MUST
  choose to use one of the challenges with the strongest auth-scheme it
  understands and request credentials from the user based upon that
  challenge.

  credentials = auth-scheme #auth-param

    Note that many browsers will only recognize Basic and will require
    that it be the first auth-scheme presented. Servers should only
    include Basic if it is minimally acceptable.

  The protection space determines the domain over which credentials can
  be automatically applied. If a prior request has been authorized, the
  same credentials MAY be reused for all other requests within that
  protection space for a period of time determined by the
  authentication scheme, parameters, and/or user preference. Unless
  otherwise defined by the authentication scheme, a single protection
  space cannot extend outside the scope of its server.

  If the origin server does not wish to accept the credentials sent
  with a request, it SHOULD return a 401 (Unauthorized) response. The
  response MUST include a WWW-Authenticate header field containing at
  least one (possibly new) challenge applicable to the requested
  resource. If a proxy does not accept the credentials sent with a
  request, it SHOULD return a 407 (Proxy Authentication Required). The
  response MUST include a Proxy-Authenticate header field containing a



Franks, et al.         Standards Track               [Page 4]

RFC 2617             HTTP Authentication             June 1999


  (possibly new) challenge applicable to the proxy for the requested
  resource.

  The HTTP protocol does not restrict applications to this simple
  challenge-response mechanism for access authentication. Additional
  mechanisms MAY be used, such as encryption at the transport level or
  via message encapsulation, and with additional header fields
  specifying authentication information. However, these additional
  mechanisms are not defined by this specification.

  Proxies MUST be completely transparent regarding user agent
  authentication by origin servers. That is, they must forward the
  WWW-Authenticate and Authorization headers untouched, and follow the
  rules found in section 14.8 of [2]. Both the Proxy-Authenticate and
  the Proxy-Authorization header fields are hop-by-hop headers (see
  section 13.5.1 of [2]).

2 Basic Authentication Scheme

  The "basic" authentication scheme is based on the model that the
  client must authenticate itself with a user-ID and a password for
  each realm. The realm value should be considered an opaque string
  which can only be compared for equality with other realms on that
  server. The server will service the request only if it can validate
  the user-ID and password for the protection space of the Request-URI.
  There are no optional authentication parameters.

  For Basic, the framework above is utilized as follows:

    challenge   = "Basic" realm
    credentials = "Basic" basic-credentials

  Upon receipt of an unauthorized request for a URI within the
  protection space, the origin server MAY respond with a challenge like
  the following:

    WWW-Authenticate: Basic realm="WallyWorld"

  where "WallyWorld" is the string assigned by the server to identify
  the protection space of the Request-URI. A proxy may respond with the
  same challenge using the Proxy-Authenticate header field.

  To receive authorization, the client sends the userid and password,
  separated by a single colon (":") character, within a base64 [7]
  encoded string in the credentials.

    basic-credentials = base64-user-pass
    base64-user-pass = <base64 [4] encoding of user-pass,



Franks, et al.         Standards Track               [Page 5]

RFC 2617             HTTP Authentication             June 1999


              except not limited to 76 char/line>
    user-pass   = userid ":" password
    userid     = *<TEXT excluding ":">
    password   = *TEXT

  Userids might be case sensitive.

  If the user agent wishes to send the userid "Aladdin" and password
  "open sesame", it would use the following header field:

    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

  A client SHOULD assume that all paths at or deeper than the depth of
  the last symbolic element in the path field of the Request-URI also
  are within the protection space specified by the Basic realm value of
  the current challenge. A client MAY preemptively send the
  corresponding Authorization header with requests for resources in
  that space without receipt of another challenge from the server.
  Similarly, when a client sends a request to a proxy, it may reuse a
  userid and password in the Proxy-Authorization header field without
  receiving another challenge from the proxy server. See section 4 for
  security considerations associated with Basic authentication.

3 Digest Access Authentication Scheme

3.1 Introduction

3.1.1 Purpose

  The protocol referred to as "HTTP/1.0" includes the specification for
  a Basic Access Authentication scheme[1]. That scheme is not
  considered to be a secure method of user authentication, as the user
  name and password are passed over the network in an unencrypted form.
  This section provides the specification for a scheme that does not
  send the password in cleartext, referred to as "Digest Access
  Authentication".

  The Digest Access Authentication scheme is not intended to be a
  complete answer to the need for security in the World Wide Web. This
  scheme provides no encryption of message content. The intent is
  simply to create an access authentication method that avoids the most
  serious flaws of Basic authentication.

3.1.2 Overall Operation

  Like Basic Access Authentication, the Digest scheme is based on a
  simple challenge-response paradigm. The Digest scheme challenges
  using a nonce value. A valid response contains a checksum (by



Franks, et al.         Standards Track               [Page 6]

RFC 2617             HTTP Authentication             June 1999


  default, the MD5 checksum) of the username, the password, the given
  nonce value, the HTTP method, and the requested URI. In this way, the
  password is never sent in the clear. Just as with the Basic scheme,
  the username and password must be prearranged in some fashion not
  addressed by this document.

3.1.3 Representation of digest values

  An optional header allows the server to specify the algorithm used to
  create the checksum or digest. By default the MD5 algorithm is used
  and that is the only algorithm described in this document.

  For the purposes of this document, an MD5 digest of 128 bits is
  represented as 32 ASCII printable characters. The bits in the 128 bit
  digest are converted from most significant to least significant bit,
  four bits at a time to their ASCII presentation as follows. Each four
  bits is represented by its familiar hexadecimal notation from the
  characters 0123456789abcdef. That is, binary 0000 gets represented by
  the character '0', 0001, by '1', and so on up to the representation
  of 1111 as 'f'.

3.1.4 Limitations

  The Digest authentication scheme described in this document suffers
  from many known limitations. It is intended as a replacement for
  Basic authentication and nothing more. It is a password-based system
  and (on the server side) suffers from all the same problems of any
  password system. In particular, no provision is made in this protocol
  for the initial secure arrangement between user and server to
  establish the user's password.

  Users and implementors should be aware that this protocol is not as
  secure as Kerberos, and not as secure as any client-side private-key
  scheme. Nevertheless it is better than nothing, better than what is
  commonly used with telnet and ftp, and better than Basic
  authentication.

3.2 Specification of Digest Headers

  The Digest Access Authentication scheme is conceptually similar to
  the Basic scheme. The formats of the modified WWW-Authenticate header
  line and the Authorization header line are specified below. In
  addition, a new header, Authentication-Info, is specified.








Franks, et al.         Standards Track               [Page 7]

RFC 2617             HTTP Authentication             June 1999


3.2.1 The WWW-Authenticate Response Header

  If a server receives a request for an access-protected object, and an
  acceptable Authorization header is not sent, the server responds with
  a "401 Unauthorized" status code, and a WWW-Authenticate header as
  per the framework defined above, which for the digest scheme is
  utilized as follows:

    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

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

  realm
  A string to be displayed to users so they know which username and
  password to use. 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.com ".

  domain
  A quoted, space-separated list of URIs, as specified in RFC XURI
  [7], that define the protection space. If a URI is an abs_path, it
  is relative to the canonical root URL (see section 1.2 above) of
  the server being accessed. An absoluteURI in this list may refer to
  a different server than the one being accessed. The client can use
  this list to determine the set of URIs for which the same
  authentication information may be sent: any URI that has a URI in
  this list as a prefix (after both have been made absolute) may be
  assumed to be in the same protection space. If this directive is
  omitted or its value is empty, the client should assume that the
  protection space consists of all URIs on the responding server.



Franks, et al.         Standards Track               [Page 8]

RFC 2617             HTTP Authentication             June 1999


  This directive is not meaningful in Proxy-Authenticate headers, for
  which the protection space is always the entire proxy; if present
  it should be ignored.

  nonce
  A server-specified data string which should be uniquely generated
  each time a 401 response is made. It is recommended that this
  string be base64 or hexadecimal data. Specifically, since the
  string is passed in the header lines as a quoted string, the
  double-quote character is not allowed.

  The contents of the nonce are implementation dependent. The quality
  of the implementation depends on a good choice. A nonce might, for
  example, be constructed as the base 64 encoding of

      time-stamp H(time-stamp ":" ETag ":" private-key)

  where time-stamp is a server-generated time or other non-repeating
  value, ETag is the value of the HTTP ETag header associated with
  the requested entity, and private-key is data known only to the
  server. With a nonce of this form a server would recalculate the
  hash portion after receiving the client authentication header and
  reject the request if it did not match the nonce from that header
  or if the time-stamp value is not recent enough. In this way the
  server can limit the time of the nonce's validity. The inclusion of
  the ETag prevents a replay request for an updated version of the
  resource. (Note: including the IP address of the client in the
  nonce would appear to offer the server the ability to limit the
  reuse of the nonce to the same client that originally got it.
  However, that would break proxy farms, where requests from a single
  user often go through different proxies in the farm. Also, IP
  address spoofing is not that hard.)

  An implementation might choose not to accept a previously used
  nonce or a previously used digest, in order to protect against a
  replay attack. Or, an implementation might choose to use one-time
  nonces or digests for POST or PUT requests and a time-stamp for GET
  requests. For more details on the issues involved see section 4.
  of this document.

  The nonce is opaque to the client.

  opaque
  A string of data, specified by the server, which should be returned
  by the client unchanged in the Authorization header of subsequent
  requests with URIs in the same protection space. It is recommended
  that this string be base64 or hexadecimal data.




Franks, et al.         Standards Track               [Page 9]

RFC 2617             HTTP Authentication             June 1999


  stale
  A flag, indicating that the previous request from the client was
  rejected because the nonce value was stale. If stale is TRUE
  (case-insensitive), the client may wish to simply retry the request
  with a new encrypted response, without reprompting the user for a
  new username and password. The server should only set stale to TRUE
  if it receives a request for which the nonce is invalid but with a
  valid digest for that nonce (indicating that the client knows the
  correct username/password). If stale is FALSE, or anything other
  than TRUE, or the stale directive is not present, the username
  and/or password are invalid, and new values must be obtained.

  algorithm
  A string indicating a pair of algorithms used to produce the digest
  and a checksum. If this is not present it is assumed to be "MD5".
  If the algorithm is not understood, the challenge should be ignored
  (and a different one used, if there is more than one).

  In this document the string obtained by applying the digest
  algorithm to the data "data" with secret "secret" will be denoted
  by KD(secret, data), and the string obtained by applying the
  checksum algorithm to the data "data" will be denoted H(data). The
  notation unq(X) means the value of the quoted-string X without the
  surrounding quotes.

  For the "MD5" and "MD5-sess" algorithms

      H(data) = MD5(data)

  and

      KD(secret, data) = H(concat(secret, ":", data))

  i.e., the digest is the MD5 of the secret concatenated with a colon
  concatenated with the data. The "MD5-sess" algorithm is intended to
  allow efficient 3rd party authentication servers; for the
  difference in usage, see the description in section 3.2.2.2.

  qop-options
  This directive is optional, but is made so only for backward
  compatibility with RFC 2069 [6]; it SHOULD be used by all
  implementations compliant with this version of the Digest scheme.
  If present, it is 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; see the





Franks, et al.         Standards Track             [Page 10]

RFC 2617             HTTP Authentication             June 1999


  descriptions below for calculating the response directive value for
  the application of this choice. Unrecognized options MUST be
  ignored.

  auth-param
  This directive allows for future extensions. Any unrecognized
  directive MUST be ignored.

3.2.2 The Authorization Request Header

  The client is expected to retry the request, passing an Authorization
  header line, which is defined according to the framework above,
  utilized as follows.

    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   ; As specified by HTTP/1.1
    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"

  The values of the opaque and algorithm fields must be those supplied
  in the WWW-Authenticate response header for the entity being
  requested.

  response
  A string of 32 hex digits computed as defined below, which proves
  that the user knows a password

  username
  The user's name in the specified realm.





Franks, et al.         Standards Track             [Page 11]

RFC 2617             HTTP Authentication             June 1999


  digest-uri
  The URI from Request-URI of the Request-Line; duplicated here
  because proxies are allowed to change the Request-Line in transit.

  qop
  Indicates what "quality of protection" the client has applied to
  the message. If present, its value MUST be one of the alternatives
  the server indicated it supports in the WWW-Authenticate header.
  These values affect the computation of the request-digest. Note
  that this is a single token, not a quoted list of alternatives as
  in WWW- Authenticate. This directive is optional in order to
  preserve backward compatibility with a minimal implementation of
  RFC 2069 [6], but SHOULD be used if the server indicated that qop
  is supported by providing a qop directive in the WWW-Authenticate
  header field.

  cnonce
  This MUST be specified if a qop directive is sent (see above), and
  MUST NOT be specified if the server did not send a qop directive in
  the WWW-Authenticate header field. 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, to provide mutual
  authentication, and to provide some message integrity protection.
  See the descriptions below of the calculation of the response-
  digest and request-digest values.

  nonce-count
  This MUST be specified if a qop directive is sent (see above), and
  MUST NOT be specified if the server did not send a qop directive in
  the WWW-Authenticate header field. 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 request-digest value.

  auth-param
  This directive allows for future extensions. Any unrecognized
  directive MUST be ignored.

  If a directive or its value is improper, or required directives are
  missing, the proper response is 400 Bad Request. If the request-
  digest is invalid, then a login failure should be logged, since
  repeated login failures from a single client may indicate an attacker
  attempting to guess passwords.



Franks, et al.         Standards Track             [Page 12]

RFC 2617             HTTP Authentication             June 1999


  The definition of request-digest above indicates the encoding for its
  value. The following definitions show how the value is computed.

3.2.2.1 Request-Digest

  If the "qop" value is "auth" or "auth-int":

    request-digest = <"> < KD ( H(A1),   unq(nonce-value)
                            ":" nc-value
                            ":" unq(cnonce-value)
                            ":" unq(qop-value)
                            ":" H(A2)
                      ) <">

  If the "qop" directive is not present (this construction is for
  compatibility with RFC 2069):

    request-digest =
          <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) >
  <">

  See below for the definitions for A1 and A2.

3.2.2.2 A1

  If the "algorithm" directive's value is "MD5" or is unspecified, then
  A1 is:

    A1     = unq(username-value) ":" unq(realm-value) ":" passwd

  where

    passwd   = < user's password >

  If the "algorithm" directive's value is "MD5-sess", then A1 is
  calculated only once - on the first request by the client following
  receipt of a WWW-Authenticate challenge from the server. It uses the
  server nonce from that challenge, and the first client nonce value to
  construct A1 as follows:

    A1     = H( unq(username-value) ":" unq(realm-value)
              ":" passwd )
              ":" unq(nonce-value) ":" unq(cnonce-value)

  This creates a 'session key' for the authentication of subsequent
  requests and responses which is different for each "authentication
  session", thus limiting the amount of material hashed with any one
  key. (Note: see further discussion of the authentication session in



Franks, et al.         Standards Track             [Page 13]

RFC 2617             HTTP Authentication             June 1999


  section 3.3.) Because the server need only use the hash of the user
  credentials in order to create the A1 value, this construction could
  be used in conjunction with a third party authentication service so
  that the web server would not need the actual password value. The
  specification of such a protocol is beyond the scope of this
  specification.

3.2.2.3 A2

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

    A2     = Method ":" digest-uri-value

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

    A2     = Method ":" digest-uri-value ":" H(entity-body)

3.2.2.4 Directive values and quoted-string

  Note that the value of many of the directives, such as "username-
  value", are defined as a "quoted-string". However, the "unq" notation
  indicates that surrounding quotation marks are removed in forming the
  string A1. Thus if the Authorization header includes the fields

  username="Mufasa", realm=myhost@testrealm.com

  and the user Mufasa has password "Circle Of Life" then H(A1) would be
  H(Mufasa:myhost@testrealm.com:Circle Of Life) with no quotation marks
  in the digested string.

  No white space is allowed in any of the strings to which the digest
  function H() is applied unless that white space exists in the quoted
  strings or entity body whose contents make up the string to be
  digested. For example, the string A1 illustrated above must be

    Mufasa:myhost@testrealm.com:Circle Of Life

  with no white space on either side of the colons, but with the white
  space between the words used in the password value. Likewise, the
  other strings digested by H() must not have white space on either
  side of the colons which delimit their fields unless that white space
  was in the quoted strings or entity body being digested.

  Also note that if integrity protection is applied (qop=auth-int), the
  H(entity-body) is the hash of the entity body, not the message body -
  it is computed before any transfer encoding is applied by the sender




Franks, et al.         Standards Track             [Page 14]

RFC 2617             HTTP Authentication             June 1999


  and after it has been removed by the recipient. Note that this
  includes multipart boundaries and embedded headers in each part of
  any multipart content-type.

3.2.2.5 Various considerations

  The "Method" value is the HTTP request method as specified in section
  5.1.1 of [2]. The "request-uri" value is the Request-URI from the
  request line as specified in section 5.1.2 of [2]. This may be "*",
  an "absoluteURL" or an "abs_path" as specified in section 5.1.2 of
  [2], but it MUST agree with the Request-URI. In particular, it MUST
  be an "absoluteURL" if the Request-URI is an "absoluteURL". The
  "cnonce-value" is an optional client-chosen value whose purpose is
  to foil chosen plaintext attacks.

  The authenticating server must assure that the resource designated by
  the "uri" directive is the same as the resource specified in the
  Request-Line; if they are not, the server SHOULD return a 400 Bad
  Request error. (Since this may be a symptom of an attack, server
  implementers may want to consider logging such errors.) The purpose
  of duplicating information from the request URL in this field is to
  deal with the possibility that an intermediate proxy may alter the
  client's Request-Line. This altered (but presumably semantically
  equivalent) request would not result in the same digest as that
  calculated by the client.

  Implementers should be aware of how authenticated transactions
  interact with shared caches. The HTTP/1.1 protocol specifies that
  when a shared cache (see section 13.7 of [2]) has received a request
  containing an Authorization header and a response from relaying that
  request, it MUST NOT return that response as a reply to any other
  request, unless one of two Cache-Control (see section 14.9 of [2])
  directives was present in the response. If the original response
  included the "must-revalidate" Cache-Control directive, the cache MAY
  use the entity of that response in replying to a subsequent request,
  but MUST first revalidate it with the origin server, using the
  request headers from the new request to allow the origin server to
  authenticate the new request. Alternatively, if the original response
  included the "public" Cache-Control directive, the response entity
  MAY be returned in reply to any subsequent request.

3.2.3 The Authentication-Info Header

  The Authentication-Info header is used by the server to communicate
  some information regarding the successful authentication in the
  response.





Franks, et al.         Standards Track             [Page 15]

RFC 2617             HTTP Authentication             June 1999


    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 <">

  The value of the nextnonce directive is the nonce the server wishes
  the client to use for a future authentication response. The server
  may send the Authentication-Info header with a nextnonce field as a
  means of implementing one-time or otherwise changing nonces. If the
  nextnonce field is present the client SHOULD use it when constructing
  the Authorization header for its next request. Failure of the client
  to do so may result in a request to re-authenticate from the server
  with the "stale=TRUE".

  Server implementations should carefully consider the performance
  implications of the use of this mechanism; pipelined requests will
  not be possible if every response includes a nextnonce directive
  that must be used on the next request received by the server.
  Consideration should be given to the performance vs. security
  tradeoffs of allowing an old nonce value to be used for a limited
  time to permit request pipelining. Use of the nonce-count can
  retain most of the security advantages of a new server nonce
  without the deleterious affects on pipelining.

  message-qop
  Indicates the "quality of protection" options applied to the
  response by the server. The value "auth" indicates authentication;
  the value "auth-int" indicates authentication with integrity
  protection. The server SHOULD use the same value for the message-
  qop directive in the response as was sent by the client in the
  corresponding request.

  The optional response digest in the "response-auth" directive
  supports mutual authentication -- the server proves that it knows the
  user's secret, and with qop=auth-int also provides limited integrity
  protection of the response. The "response-digest" value is calculated
  as for the "request-digest" in the Authorization header, except that
  if "qop=auth" or is not specified in the Authorization header for the
  request, A2 is

    A2     = ":" digest-uri-value

  and if "qop=auth-int", then A2 is

    A2     = ":" digest-uri-value ":" H(entity-body)



Franks, et al.         Standards Track             [Page 16]

RFC 2617             HTTP Authentication             June 1999


  where "digest-uri-value" is the value of the "uri" directive on the
  Authorization header in the request. The "cnonce-value" and "nc-
  value" MUST be the ones for the client request to which this message
  is the response. The "response-auth", "cnonce", and "nonce-count"
  directives MUST BE present if "qop=auth" or "qop=auth-int" is
  specified.

  The Authentication-Info header is allowed in the trailer of an HTTP
  message transferred via chunked transfer-coding.

3.3 Digest Operation

  Upon receiving the Authorization header, the server may check its
  validity by looking up the password that corresponds to the submitted
  username. Then, the server must perform the same digest operation
  (e.g., MD5) performed by the client, and compare the result to the
  given request-digest value.

  Note that the HTTP server does not actually need to know the user's
  cleartext password. As long as H(A1) is available to the server, the
  validity of an Authorization header may be verified.

  The client response to a WWW-Authenticate challenge for a protection
  space starts an authentication session with that protection space.
  The authentication session lasts until the client receives another
  WWW-Authenticate challenge from any server in the protection space. A
  client should remember the username, password, nonce, nonce count and
  opaque values associated with an authentication session to use to
  construct the Authorization header in future requests within that
  protection space. The Authorization header may be included
  preemptively; doing so improves server efficiency and avoids extra
  round trips for authentication challenges. The server may choose to
  accept the old Authorization header information, even though the
  nonce value included might not be fresh. Alternatively, the server
  may return a 401 response with a new nonce value, causing the client
  to retry the request; by specifying stale=TRUE with this response,
  the server tells the client to retry with the new nonce, but without
  prompting for a new username and password.

  Because the client is required to return the value of the opaque
  directive given to it by the server for the duration of a session,
  the opaque data may be used to transport authentication session state
  information. (Note that any such use can also be accomplished more
  easily and safely by including the state in the nonce.) For example,
  a server could be responsible for authenticating content that
  actually sits on another server. It would achieve this by having the
  first 401 response include a domain directive whose value includes a
  URI on the second server, and an opaque directive whose value



Franks, et al.         Standards Track             [Page 17]

RFC 2617             HTTP Authentication             June 1999


  contains the state information. The client will retry the request, at
  which time the server might respond with a 301/302 redirection,
  pointing to the URI on the second server. The client will follow the
  redirection, and pass an Authorization header , including the
  <opaque> data.

  As with the basic scheme, proxies must be completely transparent in
  the Digest access authentication scheme. That is, they must forward
  the WWW-Authenticate, Authentication-Info and Authorization headers
  untouched. If a proxy wants to authenticate a client before a request
  is forwarded to the server, it can be done using the Proxy-
  Authenticate and Proxy-Authorization headers described in section 3.6
  below.

3.4 Security Protocol Negotiation

  It is useful for a server to be able to know which security schemes a
  client is capable of handling.

  It is possible that a server may want to require Digest as its
  authentication method, even if the server does not know that the
  client supports it. A client is encouraged to fail gracefully if the
  server specifies only authentication schemes it cannot handle.

3.5 Example

  The following example assumes that an access-protected document is
  being requested from the server via a GET request. The URI of the
  document is " http://www.nowhere.org/dir/index.html ". Both client and
  server know that the username for this document is "Mufasa", and the
  password is "Circle Of Life" (with one space between each of the
  three words).

  The first time the client requests the document, no Authorization
  header is sent, so the server responds with:

      HTTP/1.1 401 Unauthorized
      WWW-Authenticate: Digest
          realm=" testrealm@host.com ",
          qop="auth,auth-int",
          nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
          opaque="5ccc069c403ebaf9f0171e9517f40e41"

  The client may prompt the user for the username and password, after
  which it will respond with a new request, including the following
  Authorization header:





Franks, et al.         Standards Track             [Page 18]

RFC 2617             HTTP Authentication             June 1999


      Authorization: Digest username="Mufasa",
          realm=" testrealm@host.com ",
          nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
          uri="/dir/index.html",
          qop=auth,
          nc=00000001,
          cnonce="0a4f113b",
          response="6629fae49393a05397450978507c4ef1",
          opaque="5ccc069c403ebaf9f0171e9517f40e41"

3.6 Proxy-Authentication and Proxy-Authorization

  The digest authentication scheme may also be used for authenticating
  users to proxies, proxies to proxies, or proxies to origin servers by
  use of the Proxy-Authenticate and Proxy-Authorization headers. These
  headers are instances of the Proxy-Authenticate and Proxy-
  Authorization headers specified in sections 10.33 and 10.34 of the
  HTTP/1.1 specification [2] and their behavior is subject to
  restrictions described there. The transactions for proxy
  authentication are very similar to those already described. Upon
  receiving a request which requires authentication, the proxy/server
  must issue the "407 Proxy Authentication Required" response with a
  "Proxy-Authenticate" header. The digest-challenge used in the
  Proxy-Authenticate header is the same as that for the WWW-
  Authenticate header as defined above in section 3.2.1.

  The client/proxy must then re-issue the request with a Proxy-
  Authorization header, with directives as specified for the
  Authorization header in section 3.2.2 above.

  On subsequent responses, the server sends Proxy-Authentication-Info
  with directives the same as those for the Authentication-Info header
  field.

  Note that in principle a client could be asked to authenticate itself
  to both a proxy and an end-server, but never in the same response.

4 Security Considerations

4.1 Authentication of Clients using Basic Authentication

  The Basic authentication scheme is not a secure method of user
  authentication, nor does it in any way protect the entity, which is
  transmitted in cleartext across the physical network used as the
  carrier. HTTP does not prevent additional authentication schemes and
  encryption mechanisms from being employed to increase security or the
  addition of enhancements (such as schemes to use one-time passwords)
  to Basic authentication.



Franks, et al.         Standards Track             [Page 19]

RFC 2617             HTTP Authentication             June 1999


  The most serious flaw in Basic authentication is that it results in
  the essentially cleartext transmission of the user's password over
  the physical network. It is this problem which Digest Authentication
  attempts to address.

  Because Basic authentication involves the cleartext transmission of
  passwords it SHOULD NOT be used (without enhancements) to protect
  sensitive or valuable information.

  A common use of Basic authentication is for identification purposes
  -- requiring the user to provide a user name and password as a means
  of identification, for example, for purposes of gathering accurate
  usage statistics on a server. When used in this way it is tempting to
  think that there is no danger in its use if illicit access to the
  protected documents is not a major concern. This is only correct if
  the server issues both user name and password to the users and in
  particular does not allow the user to choose his or her own password.
  The danger arises because naive users frequently reuse a single
  password to avoid the task of maintaining multiple passwords.

  If a server permits users to select their own passwords, then the
  threat is not only unauthorized access to documents on the server but
  also unauthorized access to any other resources on other systems that
  the user protects with the same password. Furthermore, in the
  server's password database, many of the passwords may also be users'
  passwords for other sites. The owner or administrator of such a
  system could therefore expose all users of the system to the risk of
  unauthorized access to all those sites if this information is not
  maintained in a secure fashion.

  Basic Authentication is also vulnerable to spoofing by counterfeit
  servers. If a user can be led to believe that he is connecting to a
  host containing information protected by Basic authentication when,
  in fact, he is connecting to a hostile server or gateway, then the
  attacker can request a password, store it for later use, and feign an
  error. This type of attack is not possible with Digest
  Authentication. Server implementers SHOULD guard against the
  possibility of this sort of counterfeiting by gateways or CGI
  scripts. In particular it is very dangerous for a server to simply
  turn over a connection to a gateway. That gateway can then use the
  persistent connection mechanism to engage in multiple transactions
  with the client while impersonating the original server in a way that
  is not detectable by the client.

4.2 Authentication of Clients using Digest Authentication

  Digest Authentication does not provide a strong authentication
  mechanism, when compared to public key based mechanisms, for example.



Franks, et al.         Standards Track             [Page 20]

RFC 2617             HTTP Authentication             June 1999


  However, it is significantly 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 Basic mechanism.

  Digest Authentication offers no confidentiality protection beyond
  protecting the actual password. All of the rest of the request and
  response are available to an eavesdropper.

  Digest Authentication offers only limited integrity protection for
  the messages in either direction. If qop=auth-int mechanism is used,
  those parts of the message used in the calculation of the WWW-
  Authenticate and Authorization header field response directive values
  (see section 3.2 above) are protected. Most header fields and their
  values could be modified as a part of a man-in-the-middle attack.

  Many needs for secure HTTP transactions cannot be met by Digest
  Authentication. For those needs TLS or SHTTP are more appropriate
  protocols. In particular Digest authentication cannot be used for any
  transaction requiring confidentiality protection. Nevertheless many
  functions remain for which Digest authentication is both useful and
  appropriate. Any service in present use that uses Basic should be
  switched to Digest as soon as practical.

4.3 Limited Use Nonce Values

  The Digest scheme uses a server-specified nonce to seed the
  generation of the request-digest value (as specified in section
  3.2.2.1 above). As shown in the example nonce in section 3.2.1, the
  server is free to construct the nonce such that it may only be used
  from a particular client, for a particular resource, for a limited
  period of time or number of uses, or any other restrictions. Doing
  so strengthens the protection provided against, for example, replay
  attacks (see 4.5). However, it should be noted that the method
  chosen for generating and checking the nonce also has performance and
  resource implications. For example, a server may choose to allow
  each nonce value to be used only once by maintaining a record of
  whether or not each recently issued nonce has been returned and
  sending a next-nonce directive in the Authentication-Info header
  field of every response. This protects against even an immediate
  replay attack, but has a high cost checking nonce values, and perhaps
  more important will cause authentication failures for any pipelined
  requests (presumably returning a stale nonce indication). Similarly,
  incorporating a request-specific element such as the Etag value for a
  resource limits the use of the nonce to that version of the resource
  and also defeats pipelining. Thus it may be useful to do so for
  methods with side effects but have unacceptable performance for those
  that do not.



Franks, et al.         Standards Track             [Page 21]

RFC 2617             HTTP Authentication             June 1999


4.4 Comparison of Digest with Basic Authentication

  Both Digest and Basic Authentication are very much on the weak end of
  the security strength spectrum. But a comparison between the two
  points out the utility, even necessity, of replacing Basic by Digest.

  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 database whose use is
  restricted to paying subscribers. With Basic 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.

  By contrast, with Digest Authentication the eavesdropper only gets
  access to the transaction in question and not to the user's password.
  The information gained by the eavesdropper would permit a replay
  attack, but only with a request for the same document, and even that
  may be limited by the server's choice of nonce.

4.5 Replay Attacks

  A replay attack against Digest authentication would usually be
  pointless for a simple GET request since an eavesdropper would
  already have seen the only document he could obtain with a replay.
  This is because the URI of the requested document is digested in the
  client request and the server will only deliver that document. By
  contrast under Basic Authentication once the eavesdropper has the
  user's password, any document protected by that password is open to
  him.

  Thus, for some purposes, it is necessary to protect against replay
  attacks. A good Digest implementation can do this in various ways.
  The server created "nonce" value is implementation dependent, but if
  it contains a digest of the client IP, a time-stamp, the resource
  ETag, and a private server key (as recommended above) then a replay
  attack is not simple. An attacker must convince the server that the
  request is coming from a false IP address and must cause the server
  to deliver the document to an IP address different from the address
  to which it believes it is sending the document. An attack can only
  succeed in the period before the time-stamp expires. Digesting the
  client IP and time-stamp in the nonce permits an implementation which
  does not maintain state between transactions.

  For applications where no possibility of replay attack can be
  tolerated the server can use one-time nonce values which will not be
  honored for a second use. This requires the overhead of the server



Franks, et al.         Standards Track             [Page 22]

RFC 2617             HTTP Authentication             June 1999


  remembering which nonce values have been used until the nonce time-
  stamp (and hence the digest built with it) has expired, but it
  effectively protects against replay attacks.

  An implementation must give special attention to the possibility of
  replay attacks with POST and PUT requests. Unless the server employs
  one-time or otherwise limited-use nonces and/or insists on the use of
  the integrity protection of qop=auth-int, an attacker could replay
  valid credentials from a successful request with counterfeit form
  data or other message body. Even with the use of integrity protection
  most metadata in header fields is not protected. Proper nonce
  generation and checking provides some protection against replay of
  previously used valid credentials, but see 4.8.

4.6 Weakness Created by Multiple Authentication Schemes

  An HTTP/1.1 server may return multiple challenges with a 401
  (Authenticate) response, and each challenge may use a different
  auth-scheme. A user agent MUST choose to use the strongest auth-
  scheme it understands and request credentials from the user based
  upon that challenge.

    Note that many browsers will only recognize Basic and will require
    that it be the first auth-scheme presented. Servers should only
    include Basic if it is minimally acceptable.

  When the server offers choices of authentication schemes using the
  WWW-Authenticate header, the strength of the resulting authentication
  is only as good as that of the of the weakest of the authentication
  schemes. See section 4.8 below for discussion of particular attack
  scenarios that exploit multiple authentication schemes.

4.7 Online dictionary attacks

  If the attacker can eavesdrop, then it can test any overheard
  nonce/response pairs against 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
  once for each challenge.

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









Franks, et al.         Standards Track             [Page 23]

RFC 2617             HTTP Authentication             June 1999


4.8 Man in the Middle

  Both Basic and Digest authentication are vulnerable to "man in the
  middle" (MITM) attacks, for example, from a hostile or compromised
  proxy. Clearly, this would present all the problems of eavesdropping.
  But it also offers some additional opportunities to the attacker.

  A possible man-in-the-middle attack would be to add a weak
  authentication scheme to the set of choices, hoping that the client
  will use one that exposes the user's credentials (e.g. password). For
  this reason, the client should always use the strongest scheme that
  it understands from the choices offered.

  An even better MITM attack would be to remove all offered choices,
  replacing them with a challenge that requests only Basic
  authentication, then uses the cleartext credentials from the Basic
  authentication to authenticate to the origin server using the
  stronger scheme it requested. A particularly insidious way to mount
  such a MITM attack would be to offer a "free" proxy caching service
  to gullible users.

  User agents should consider measures such as presenting a visual
  indication at the time of the credentials request of what
  authentication scheme is to be used, or remembering the strongest
  authentication scheme ever requested by a server and produce a
  warning message before using a weaker one. It might also be a good
  idea for the user agent to be configured to demand Digest
  authentication in general, or from specific sites.

  Or, a hostile proxy might spoof the client into making a request the
  attacker wanted rather than one the client wanted. Of course, this is
  still much harder than a comparable attack against Basic
  Authentication.

4.9 Chosen plaintext attacks

  With Digest authentication, a MITM or a malicious server can
  arbitrarily choose the nonce that the client will use to compute the
  response. This is called a "chosen plaintext" attack. The ability to
  choose the nonce is known to make cryptanalysis much easier [8].

  However, no way to analyze the MD5 one-way function used by Digest
  using chosen plaintext is currently known.

  The countermeasure against this attack is for clients to be
  configured to require the use of the optional "cnonce" directive;
  this allows the client to vary the input to the hash in a way not
  chosen by the attacker.



Franks, et al.         Standards Track             [Page 24]

RFC 2617             HTTP Authentication             June 1999


4.10 Precomputed dictionary attacks

  With Digest authentication, if the attacker can execute a chosen
  plaintext attack, the attacker can precompute the response for many
  common words to a nonce of its choice, and store a dictionary of
  (response, password) pairs. Such precomputation can often be done in
  parallel on many machines. It can then use the chosen plaintext
  attack to acquire a response corresponding to that challenge, and
  just look up the password in the dictionary. Even if most passwords
  are not in the dictionary, some might be. Since the attacker gets to
  pick the challenge, the cost of computing the response for each
  password on the list can be amortized over finding many passwords. A
  dictionary with 100 million password/response pairs would take about
  3.2 gigabytes of disk storage.

  The countermeasure against this attack is to for clients to be
  configured to require the use of the optional "cnonce" directive.

4.11 Batch brute force attacks

  With Digest authentication, a MITM can execute a chosen plaintext
  attack, and can gather responses from many users to the same nonce.
  It can then find all the passwords within any subset of password
  space that would generate one of the nonce/response pairs in a single
  pass over that space. It also reduces the time to find the first
  password by a factor equal to the number of nonce/response pairs
  gathered. This search of the password space can often be done in
  parallel on many machines, and even a single machine can search large
  subsets of the password space very quickly -- reports exist of
  searching all passwords with six or fewer letters in a few hours.

  The countermeasure against this attack is to for clients to be
  configured to require the use of the optional "cnonce" directive.

4.12 Spoofing by Counterfeit Servers

  Basic Authentication is vulnerable to spoofing by counterfeit
  servers. 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 request a password, store it away for later use, and feign
  an error. This type of attack is more difficult with Digest
  Authentication -- but the client must know to demand that Digest
  authentication be used, perhaps using some of the techniques
  described above to counter "man-in-the-middle" attacks. Again, the
  user can be helped in detecting this attack by a visual indication of
  the authentication mechanism in use with appropriate guidance in
  interpreting the implications of each scheme.



Franks, et al.         Standards Track             [Page 25]

RFC 2617             HTTP Authentication             June 1999


4.13 Storing passwords

  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(A1), where H(A1) is
  the digested value of the username, realm, and password as described
  above.

  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
  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 unencrypted
  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 which any single user is likely to use. In
  particular a realm string should include the name of the host doing
  the authentication. The inability of the client to authenticate the
  server is a weakness of Digest Authentication.

4.14 Summary

  By modern cryptographic standards Digest Authentication is weak. But
  for a large range of purposes it is valuable as a replacement for
  Basic Authentication. It remedies some, but not all, weaknesses of
  Basic Authentication. Its strength may vary depending on the
  implementation. In particular the structure of the nonce (which is
  dependent on the server implementation) may affect the ease of
  mounting a replay attack. A range of server options is appropriate
  since, for example, some implementations may be willing to accept the
  server overhead of one-time nonces or digests to eliminate the
  possibility of replay. Others may satisfied with a nonce like the one
  recommended above restricted to a single IP address and a single ETag
  or with a limited lifetime.





Franks, et al.         Standards Track             [Page 26]

RFC 2617             HTTP Authentication             June 1999


  The bottom line is that *any* compliant implementation will be
  relatively weak by cryptographic standards, but *any* compliant
  implementation will be far superior to Basic Authentication.

5 Sample implementation

  The following code implements the calculations of H(A1), H(A2),
  request-digest and response-digest, and a test program which computes
  the values used in the example of section 3.5. It uses the MD5
  implementation from RFC 1321.

  File "digcalc.h":

#define HASHLEN 16
typedef char HASH[HASHLEN];
#define HASHHEXLEN 32
typedef char HASHHEX[HASHHEXLEN+1];
#define IN
#define OUT

/* calculate H(A1) as per HTTP Digest spec */
void DigestCalcHA1(
  IN char * pszAlg,
  IN char * pszUserName,
  IN char * pszRealm,
  IN char * pszPassword,
  IN char * pszNonce,
  IN char * pszCNonce,
  OUT HASHHEX SessionKey
  );

/* calculate request-digest/response-digest as per HTTP Digest spec */
void DigestCalcResponse(
  IN HASHHEX HA1,       /* H(A1) */
  IN char * pszNonce,     /* nonce from server */
  IN char * pszNonceCount, /* 8 hex digits */
  IN char * pszCNonce,     /* client nonce */
  IN char * pszQop,       /* qop-value: "", "auth", "auth-int" */
  IN char * pszMethod,     /* method from the request */
  IN char * pszDigestUri,   /* requested URL */
  IN HASHHEX HEntity,     /* H(entity body) if qop="auth-int" */
  OUT HASHHEX Response     /* request-digest or response-digest */
  );

File "digcalc.c":

#include <global.h>
#include <md5.h>



Franks, et al.         Standards Track             [Page 27]

RFC 2617             HTTP Authentication             June 1999


#include <string.h>
#include "digcalc.h"

void CvtHex(
  IN HASH Bin,
  OUT HASHHEX Hex
  )
{
  unsigned short i;
  unsigned char j;

  for (i = 0; i < HASHLEN; i++) {
    j = (Bin[i] >> 4) & 0xf;
    if (j <= 9)
        Hex[i*2] = (j + '0');
      else
        Hex[i*2] = (j + 'a' - 10);
    j = Bin[i] & 0xf;
    if (j <= 9)
        Hex[i*2+1] = (j + '0');
      else
        Hex[i*2+1] = (j + 'a' - 10);
  };
  Hex[HASHHEXLEN] = '\0';
};

/* calculate H(A1) as per spec */
void DigestCalcHA1(
  IN char * pszAlg,
  IN char * pszUserName,
  IN char * pszRealm,
  IN char * pszPassword,
  IN char * pszNonce,
  IN char * pszCNonce,
  OUT HASHHEX SessionKey
  )
{
    MD5_CTX Md5Ctx;
    HASH HA1;

    MD5Init(&Md5Ctx);
    MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
    MD5Update(&Md5Ctx, ":", 1);
    MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
    MD5Update(&Md5Ctx, ":", 1);
    MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
    MD5Final(HA1, &Md5Ctx);
    if (stricmp(pszAlg, "md5-sess") == 0) {



Franks, et al.         Standards Track             [Page 28]

RFC 2617             HTTP Authentication             June 1999


        MD5Init(&Md5Ctx);
        MD5Update(&Md5Ctx, HA1, HASHLEN);
        MD5Update(&Md5Ctx, ":", 1);
        MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
        MD5Update(&Md5Ctx, ":", 1);
        MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
        MD5Final(HA1, &Md5Ctx);
    };
    CvtHex(HA1, SessionKey);
};

/* calculate request-digest/response-digest as per HTTP Digest spec */
void DigestCalcResponse(
  IN HASHHEX HA1,       /* H(A1) */
  IN char * pszNonce,     /* nonce from server */
  IN char * pszNonceCount, /* 8 hex digits */
  IN char * pszCNonce,     /* client nonce */
  IN char * pszQop,       /* qop-value: "", "auth", "auth-int" */
  IN char * pszMethod,     /* method from the request */
  IN char * pszDigestUri,   /* requested URL */
  IN HASHHEX HEntity,     /* H(entity body) if qop="auth-int" */
  OUT HASHHEX Response     /* request-digest or response-digest */
  )
{
    MD5_CTX Md5Ctx;
    HASH HA2;
    HASH RespHash;
    HASHHEX HA2Hex;

    // calculate H(A2)
    MD5Init(&Md5Ctx);
    MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
    MD5Update(&Md5Ctx, ":", 1);
    MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
    if (stricmp(pszQop, "auth-int") == 0) {
        MD5Update(&Md5Ctx, ":", 1);
        MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
    };
    MD5Final(HA2, &Md5Ctx);
    CvtHex(HA2, HA2Hex);

    // calculate response
    MD5Init(&Md5Ctx);
    MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
    MD5Update(&Md5Ctx, ":", 1);
    MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
    MD5Update(&Md5Ctx, ":", 1);
    if (*pszQop) {



Franks, et al.         Standards Track             [Page 29]

RFC 2617             HTTP Authentication             June 1999


      MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
      MD5Update(&Md5Ctx, ":", 1);
      MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
      MD5Update(&Md5Ctx, ":", 1);
      MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
      MD5Update(&Md5Ctx, ":", 1);
    };
    MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
    MD5Final(RespHash, &Md5Ctx);
    CvtHex(RespHash, Response);
};

File "digtest.c":


#include <stdio.h>
#include "digcalc.h"

void main(int argc, char ** argv) {

    char * pszNonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
    char * pszCNonce = "0a4f113b";
    char * pszUser = "Mufasa";
    char * pszRealm = " testrealm@host.com ";
    char * pszPass = "Circle Of Life";
    char * pszAlg = "md5";
    char szNonceCount[9] = "00000001";
    char * pszMethod = "GET";
    char * pszQop = "auth";
    char * pszURI = "/dir/index.html";
    HASHHEX HA1;
    HASHHEX HA2 = "";
    HASHHEX Response;

    DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,
pszCNonce, HA1);
    DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
    pszMethod, pszURI, HA2, Response);
    printf("Response = %s\n", Response);
};











Franks, et al.         Standards Track             [Page 30]

RFC 2617             HTTP Authentication             June 1999


6 Acknowledgments

  Eric W. Sink, of AbiSource, Inc., was one of the original authors
  before the specification underwent substantial revision.

  In addition to the authors, valuable discussion instrumental in
  creating this document has come from Peter J. Churchyard, Ned Freed,
  and David M. Kristol.

  Jim Gettys and Larry Masinter edited this document for update.

7 References

  [1] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext
    Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.

  [2] Fielding, R., Gettys, J., Mogul, J., Frysyk, H., Masinter, L.,
    Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol --
    HTTP/1.1", RFC 2616, June 1999.

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

  [4] Freed, N. and N. Borenstein. "Multipurpose Internet Mail
    Extensions (MIME) Part One: Format of Internet Message Bodies",
    RFC 2045, November 1996.

  [5] Dierks, T. and C. Allen "The TLS Protocol, Version 1.0", RFC
    2246, January 1999.

  [6] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
    Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP :
    Digest Access Authentication", RFC 2069, January 1997.

  [7] Berners Lee, T, Fielding, R. and L. Masinter, "Uniform Resource
    Identifiers (URI): Generic Syntax", RFC 2396, August 1998.

  [8] Kaliski, B.,Robshaw, M., "Message Authentication with MD5",
    CryptoBytes, Sping 1995, RSA Inc,
    ( http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm )

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

  [10] Morgan, B., Alvestrand, H., Hodges, J., Wahl, M.,
    "Authentication Methods for LDAP", Work in Progress.




Franks, et al.         Standards Track             [Page 31]

RFC 2617             HTTP Authentication             June 1999


8 Authors' Addresses

  John Franks
  Professor of Mathematics
  Department of Mathematics
  Northwestern University
  Evanston, IL 60208-2730, USA

  EMail: john@math.nwu.edu


  Phillip M. Hallam-Baker
  Principal Consultant
  Verisign Inc.
  301 Edgewater Place
  Suite 210
  Wakefield MA 01880, USA

  EMail: pbaker@verisign.com


  Jeffery L. Hostetler
  Software Craftsman
  AbiSource, Inc.
  6 Dunlap Court
  Savoy, IL 61874

  EMail: jeff@AbiSource.com


  Scott D. Lawrence
  Agranat Systems, Inc.
  5 Clocktower Place, Suite 400
  Maynard, MA 01754, USA

  EMail: lawrence@agranat.com


  Paul J. Leach
  Microsoft Corporation
  1 Microsoft Way
  Redmond, WA 98052, USA

  EMail: paulle@microsoft.com







Franks, et al.         Standards Track             [Page 32]

RFC 2617             HTTP Authentication             June 1999


  Ari Luotonen
  Member of Technical Staff
  Netscape Communications Corporation
  501 East Middlefield Road
  Mountain View, CA 94043, USA


  Lawrence C. Stewart
  Open Market, Inc.
  215 First Street
  Cambridge, MA 02142, USA

  EMail: stewart@OpenMarket.com






































Franks, et al.         Standards Track             [Page 33]

RFC 2617             HTTP Authentication             June 1999


9. Full Copyright Statement

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

  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.



















Franks, et al.         Standards Track             [Page 34]


总数:1 页次:1/1 首页 尾页  
总数:1 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1