HTTP Authentication: Basic and Digest Access Authentication
obsoleted by
- rfc-7235 — Hypertext Transfer Protocol (HTTP/1.1): Authentication
- rfc-7615 — HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields
- rfc-7616 — HTTP Digest Access Authentication
- rfc-7617 — The 'Basic' HTTP Authentication Scheme
obsoletes
- rfc-2069 — An Extension to HTTP : Digest Access Authentication
Extracted elements (29)
The digest-uri field is duplicated from the Request-URI in the Authorization header because proxies are allowed to change the Request-Line in transit. Including the URI in the digest allows the server to detect proxy modification, which would produce a mismatched digest and may indicate an attack.
The MD5-sess algorithm computes A1 as H(username:realm:password) ":" nonce ":" cnonce, creating a per-session key. This limits the amount of material hashed with any one key and enables third-party authentication servers to operate using only H(A1) without knowing the plaintext password.
The opaque directive allows the server to transport authentication session state information that the client must return unchanged. This enables cross-server authentication scenarios where the first server embeds state in the opaque value, which is carried through subsequent requests to a second server.
The recommended nonce construction is base64(timestamp H(timestamp ":" ETag ":" private-key)), enabling the server to validate freshness and bind the nonce to a specific resource version. Including the client IP was considered but rejected because it breaks proxy farms and IP spoofing is not difficult.
For backward compatibility with RFC 2069, the qop directive is optional in the Authorization header. When qop is absent, request-digest is computed as KD(H(A1), nonce ":" H(A2)) without nc, cnonce, or qop fields. New implementations SHOULD use qop to gain replay protection.
Many browsers only recognize Basic authentication and require it to be listed first in a multi-scheme WWW-Authenticate response. Servers should include Basic only if it is minimally acceptable, because offering it alongside Digest reduces overall security to that of the weaker scheme.
A 401 (Unauthorized) response MUST include a WWW-Authenticate header field containing at least one challenge applicable to the requested resource. A 407 (Proxy Authentication Required) response MUST include a Proxy-Authenticate header field containing at least one challenge applicable to the proxy for the requested resource.
A user agent MUST choose to use the strongest auth-scheme it understands from the set of challenges offered by the server in a WWW-Authenticate header, and request credentials from the user based upon that challenge.
Basic authentication SHOULD NOT be used (without enhancements such as TLS) to protect sensitive or valuable information, because it results in the essentially cleartext transmission of the user's password over the physical network.
If the nextnonce field is present in Authentication-Info, the client SHOULD use it when constructing the Authorization header for its next request. Failure to do so may result in a re-authentication request from the server with stale=TRUE.
Proxies MUST be completely transparent regarding user agent authentication by origin servers; they must forward the WWW-Authenticate and Authorization headers untouched. Proxy-Authenticate and Proxy-Authorization are hop-by-hop headers and must not be forwarded end-to-end.
The cnonce directive MUST be specified in the Authorization header if a qop directive was sent by the server, and MUST NOT be specified if the server did not send a qop directive. Likewise, nonce-count (nc) MUST be present if and only if qop is present.
The digest-uri value in the Authorization header MUST agree with the Request-URI; in particular it MUST be an absoluteURL if the Request-URI is an absoluteURL. If they differ, the server SHOULD return a 400 Bad Request error.
The qop-options directive SHOULD be used by all implementations compliant with this version of the Digest scheme; it is made optional only for backward compatibility with RFC 2069. Unrecognized qop-options MUST be ignored.
The response-auth, cnonce, and nonce-count directives MUST be present in Authentication-Info if qop=auth or qop=auth-int was specified in the corresponding request's Authorization header.
The Authentication-Info header is sent by the server in successful Digest authentication responses and may contain: nextnonce, message-qop, response-auth (mutual authentication digest proving server knows the user's secret), cnonce, and nonce-count.
The Basic authentication scheme transmits credentials as base64(userid ":" password). The realm directive identifies the protection space; there are no optional authentication parameters. A client SHOULD assume all paths at or deeper than the last symbolic element of the Request-URI are within the same protection space.
The Digest Authorization request header includes: username, realm, nonce, digest-uri, response (32 hex digits), algorithm (optional), cnonce (required if qop present), opaque (if provided by server), message-qop (optional but SHOULD be used), and nonce-count (required if qop present).
The Digest WWW-Authenticate challenge includes directives: realm (required), domain (optional), nonce (required), opaque (optional), stale (optional), algorithm (optional, default MD5), and qop-options (optional but SHOULD be present). Any unrecognized directive MUST be ignored.
The protection space is defined by the realm value combined with the canonical root URL of the server. Credentials may be automatically reused for all URIs within the same protection space. A single protection space cannot extend outside the scope of its server unless explicitly defined by the domain directive.
The stale flag in WWW-Authenticate indicates the previous request was rejected only because the nonce was stale but the digest was otherwise valid. When stale=TRUE the client may retry with a new nonce without reprompting the user; stale=FALSE or absent means credentials themselves are invalid.
A MITM or malicious server controlling the nonce can mount chosen plaintext, precomputed dictionary, and batch brute-force attacks against Digest. The countermeasure is requiring clients to use the cnonce directive, which adds client-chosen randomness to the hash and defeats nonce-chosen precomputation.
Basic authentication transmits passwords in cleartext (base64 is encoding, not encryption) and is vulnerable to eavesdropping, server spoofing, and password reuse attacks across sites. Administrators who allow user-chosen passwords expose all users to unauthorized access wherever those passwords are reused.
Both Basic and Digest authentication are vulnerable to man-in-the-middle attacks. A hostile proxy can strip stronger schemes from WWW-Authenticate, leaving only Basic, harvest the cleartext password, then authenticate to the origin server using Digest. Clients should track the strongest scheme ever seen from a server and warn on downgrade.
Digest authentication password files store H(A1) = MD5(username:realm:password). A compromised file grants immediate access to that realm without decryption. Because the realm is included in the hash, a breach of one realm's file does not directly compromise other realms sharing the same username and password.
Replay attacks against Digest are inherently limited because the requested URI is included in the digest, constraining a replay to fetching only that specific document. Servers can further restrict replay by using nonces that embed timestamps and ETags, or by using one-time nonces at the cost of HTTP pipelining.
An MD5 digest is represented as 32 lowercase ASCII hexadecimal characters (LHEX) encoding the 128-bit value most-significant-bit first. The nonce-count (nc-value) field is exactly 8 hex digits (8LHEX); the request-digest is a quoted string of 32LHEX.
Basic credentials are encoded as base64(userid ":" password) where userid is TEXT excluding ":" and password is any TEXT. The resulting value is placed in the Authorization header as "Basic <base64-user-pass>", with no 76-character line-length limit unlike standard base64.
For qop=auth or auth-int, request-digest = KD(H(A1), nonce ":" nc ":" cnonce ":" qop ":" H(A2)). For RFC-2069 compatibility without qop, request-digest = KD(H(A1), nonce ":" H(A2)). A1 = username ":" realm ":" password (MD5) or H(username ":" realm ":" password) ":" nonce ":" cnonce (MD5-sess). A2 = method ":" uri for auth; method ":" uri ":" H(entity-body) for auth-int.