Understanding HTTP Digest Access Authentication

Share this article

Digest Access Authentication is one method that a client and server can use to exchange credentials over HTTP. This method uses a combination of the password and other bits of information to create an MD5 hash which is then sent to the server to authenticate. Sending a hash avoids the problems with sending a password in clear text, a shortfall of Basic Access Authentication. Digest Access was originally defined in RFC 2069, and optional security enhancements were later added in RFC 2617 which should be considered the current standard if you wish to implement this method yourself. We’ll have a look at both in this article.

The Problem with Basic Access Authentication

First, lets look a Basic Access Authentication. With your browser, you request some sort of object that requires you to authenticate yourself. If the browser hasn’t cached credentials you’ve already provided, you’ll be met with a “HTTP 401 Not Authorized” response which includes the following header:
WWW-Authenticate: Basic realm="example.com"
The client/browser is then expected to respond with the appropriate credentials in order to be allowed access. The username and password are concatenated together, like “admin:p@ssw0rd”, This string is then Base64 encoded. The encoded string (YWRtaW46cEBzc3cwcmQ=) is used in an Authorization header which is sent back to the server.
Authorization: Basic YWRtaW46cEBzc3cwcmQ=
When the server receives this request, it notices the Authorization header and applies the steps in reverse (decode and split the resulting string) to get the original username and password. The process can then do whatever lookup/verification is necessary with the credentials. The major problem here is that Base64 is a data transfer scheme; it’s not a hashing or encryption scheme. It may as well be clear text. Digest Access Authentication tries to improve upon this by sending the password as a hashed value, which is much harder (not impossible) to reverse engineer a clear text value from.

Working with Digest Access Authentication

When working with Digest Access Authentication, it’s the server who must make the first move when it discovers a client is trying to access a restricted area. There are a few values the server needs to provide as part of the WWW-Authenticate header that the client needs. The server generates a value, referred to as nonce, which should be unique for each request. It’s recommended this value be either Base64 or hexadecimal, specifically because it will be enclosed in double quotes and we want to ensure there are no double quotes in the string. The nonce will be used by the client to generate a hash to send back to the server. In PHP, applying md5() to a unique string is generally sufficient.
<?php
$nonce = md5(uniqid());
The next value needed by the client is opaque. This is another unique string generated by the server and is expected to be sent and returned by the client unaltered.
<?php
$opaque = md5(uniqid());
The last value, realm, is just a string to display to users so they know which username and password they should provide. It’s also used by the client to generate a hash to send back to the server.
<?php
$realm = 'Authorized users of example.com';
All of these values are used to compose the WWW-Authenticate directive and send as a response to the client.
<?php
if (empty($_SERVER['PHP_AUTH_DIGEST']) {
    header('HTTP/1.1 401 Unauthorized');
    header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', $realm, $nonce, $opaque));
    header('Content-Type: text/html');
    echo '<p>You need to authenticate.</p>';
    exit;
}
When the client receives this response, it has to compute a return hash. It does so by concatenating the username, realm, and password and hashing the result with MD5 as follows:
  1. Compute A1 as MD5("username:realm:password").
  2. Compute A2 as MD5("requestMethod:requestURI").
  3. Compute the final hash, know as “response”, as MD5("A1:nonce:A2").
The client sends the response back to the server in an Authorization header and includes the username, realm, nonce, opaque, uri, and the computed response.
Authorization: Digest username="%s", realm="%s", nonce="%s", opaque="%s", uri="%s", response="%s"'
Note that realm, nonce, and opaque are all returned to the server unchanged. When the server receives the response, the same steps are taken to compute the server’s version of the hash. If the computed hash and the received response hash values match, then the request is considered authorized. It looks something like this:
<?php
$A1 = md5("$username:$realm:$password");
$A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri");
$response = md5("$A1:$nonce:$A2");
Of course, the user’s password is never passed to the server. To perform authentication look ups from a database then, the value of A1 can be stored. Keep in mind however the stored hash becomes invalid if you ever change your realm.

Improving on the Original Digest Access Spec

Now that you’re familiar with the workings of Digest Access Authentication from RFC 2069, let’s turn our attention to some of the enhancements that were added in 2617: qop, nc, and cnonce. qop, or quality of protection, is specified in the WWW-Authenticate header and can have a value of “auth” or “auth-int”. When no qop directive is found or when it is set to “auth”, Digest Access is used for client authentication only – the default mode which you’ve seen so far. When set to “auth-int”, an attempt is made to provide some level of integrity protection of the response as well and the client must also include the request body as part of the message digest. This allows the server to determine whether the request has been adulterated in transfer between the indented client and intended server. The client nonce, or cnonce
, is similar to nonce but is generated by the client. The cnonce figures into the response digest computed by the client and its original value is passed along to the server so that it can be used there to compare digests. This provides some response integrity and mutual authentication, in that both the client and server have a way to prove they know a shared secret. When the qop directive is sent by the server, the client must include a cnonce value. The nonce count, nc, is a hexadecimal count of the number of requests that the client has sent with a given nonce value. This way, the server can guard against replay attacks. With the enhancements, the computation of A2 and the response goes something like this:
<?php
if ($qop == 'auth-int') {
    $A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri:" . md5($respBody));
}
else {
    $A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri");
}
$response = md5("$A1:$nonce:$nc:$cnonce:$qop:$A2");

Strengths and Weaknesses of Digest Access Authentication

Digest Access has some advantages over Basic Authentication, since Basic Authentication uses a clear-text exchange of username and passwords, which is almost the same as telling the world what your password is. Digest Access passes a hashed value and not the password itself, so it’s much more secure than Basic Auth. The server nonce, which should be unique per request, will drastically change the computed hash on each new request, and the nc value provided by RFC 2617 is helpful at preventing replay attacks, whereby a malicious individual is able to intercept your request data and “replay” or repeat it as his own request. There are a few weaknesses with Digest Authentication as well. When RFC 2617 replaced the original specification, the enhancements that were added to provide extra security measures between the client and server were made purely optional, and Digest Authentication will proceed in its original RFC 2069 form when not implemented. Another problem is MD5 is not a strong hashing algorithm. All it takes is time and CPU to brute force the original value back to life. Bcrypt is preferable as it is more resilient against brute force attacks. There’s also no way for a server to verify the identity of the requesting client when using Digest Access Authentication. This opens the possibility for man in the middle attacks, where a client can be led to believe a given server is really who he thinks it is, but ends up sending his login credentials to an unknown entity. Your best bet when dealing with authentication is to use SSL and encrypt passwords using Bcrypt. You can use Basic Authentication or a home brewed authentication mechanism over SSL, but for situations where SSL is not possible for whatever reason, Digest Access is better than simple Basic Authentication and sending passwords in plain text over the public Internet. There’s a simple example of RFC-2069 HTTP Digest Access available on GitHub to accompany this article. If you’re the type of person who likes to explore and tinker, feel free to clone it. A good place to start your exercise is to make the necessary modifications to work with accounts stored in a database instead of the hard-coded credentials in the script (remember, you’ll need to calculate and store A1 as the user’s password hash for later lookup at login), and then enhance it with RFC-2617 features. Afterwards, you’ll have a pretty solid understanding of HTTP Digest Access Authentication.

Summary

By now you should have an idea of what your available HTTP authentication methods are. Basic Authentication is the easiest to implement and also the least secure. Usernames and passwords are encoded in Base64 but effectively sent to the server in plain text. Digest Authentication improves on the Basic method by sending authentication data through MD5. While MD5 is still not a strong password encryption algorithm, it is much harder to decode than the plain text/Base64 method of Basic Authentication. In its original form, there were still problems of man in the middle attacks and not being able to confirm server identity, but these weaknesses have been improved in later revisions to the RFC. SSL is the most modern and secure method of sending user authentication data over the public Internet. But when SSL is not available, please use Digest over Basic authentication. Image via Fotolia

Frequently Asked Questions (FAQs) on HTTP Digest Access Authentication

What is the Main Difference Between Basic and Digest Authentication?

Basic and Digest Authentication are both methods used to authenticate users in HTTP. The main difference lies in the level of security they offer. Basic Authentication transmits credentials in plain text, which is a security risk. On the other hand, Digest Authentication encrypts the credentials using a hashing algorithm before transmission, making it more secure. However, Digest Authentication is more complex and requires more processing power.

How Does Digest Authentication Enhance Security?

Digest Authentication enhances security by encrypting user credentials before transmission. It uses a hashing algorithm to create a unique ‘digest’ of the user’s username, password, and other information. This digest is then sent instead of the plain text password, protecting the user’s credentials even if the communication is intercepted.

What are the Limitations of Digest Authentication?

While Digest Authentication is more secure than Basic Authentication, it has its limitations. It requires more processing power, which can slow down systems. It also doesn’t protect against all types of attacks, such as man-in-the-middle attacks. Additionally, it requires the server to store passwords in plain text or a reversibly encrypted format, which can be a security risk.

How Does a Digest Authentication Process Work?

In Digest Authentication, when a client sends a request to a server, the server responds with a unique nonce value. The client then uses this nonce, along with their username, password, and other information, to create a hash. This hash is sent back to the server, which compares it to its own hash of the same information. If the hashes match, the server authenticates the client.

What is a Nonce in Digest Authentication?

A nonce (Number Used Once) in Digest Authentication is a unique value generated by the server for each authentication request. It is used to prevent replay attacks, where an attacker intercepts and retransmits a valid user’s credentials to gain unauthorized access.

Can Digest Authentication be Used with HTTPS?

Yes, Digest Authentication can be used with HTTPS. However, since HTTPS already encrypts all communication between the client and server, using Digest Authentication with HTTPS can be redundant and may unnecessarily slow down the system.

What is the Role of Quality of Protection (qop) in Digest Authentication?

Quality of Protection (qop) is an optional parameter in Digest Authentication that allows the client and server to agree on the level of protection for the communication. It can be set to ‘auth’ for authentication only, or ‘auth-int’ for authentication with integrity protection.

What is the Difference Between Digest and Kerberos Authentication?

Digest and Kerberos are both secure authentication methods, but they work differently. Digest Authentication uses a hashing algorithm to encrypt user credentials, while Kerberos uses symmetric key cryptography and a trusted third party (the Key Distribution Center) to authenticate users.

How Can I Implement Digest Authentication in My Application?

Implementing Digest Authentication in your application involves configuring your server to use Digest Authentication and writing code in your application to respond to the server’s authentication challenges. The exact steps will depend on the server and programming language you are using.

Is Digest Authentication Still Widely Used Today?

While Digest Authentication is still supported by many servers and browsers, it is not as widely used as other methods like Basic Authentication with HTTPS or token-based authentication. This is due to its limitations, such as the need for the server to store passwords in a potentially insecure format and the processing overhead of the hashing algorithm.

Sean HudgstonSean Hudgston
View Author

Sean Hudgston is well-balanced fellow who lives and works as a software engineer in Syracuse, NY. Sean has a degree in Computer Science, and when not doing things related to that, he enjoys brewing beer, making coffee, growing hops, cooking, disc golf, mowing his lawn, and playing guitar or bass as the situation may warrant.

Advanced
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week