forked from friendica/deprecated-addons
1908 lines
76 KiB
Plaintext
1908 lines
76 KiB
Plaintext
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
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]
|
|||
|
|