For a variety of reasons, I need to use digest authentication for a REST server that I have created.

I have come up with an "improvement" that I believe strengthens the algorithm against MD5 attacks without being a burden on clients. What problems can you see with my algorithm?


  • Client is a custom application written in C#.
  • Server is a JAX-RS-based REST Server written in Java and running on Tomcat.
  • All traffic between the client and server is encrypted using SSL/TLS.
  • The database contains a user_table with the following columns:

    • user_id: primary key
    • password_hash: varchar not null
    • salt: varchar not null
    • iteration_count: integer

Digest Authentication (RFC2617)

Digest authentication uses the following calculations:

nonce: server-generated number used once
nonceCount: server-generated increasing value (prevents replay attacks)
cnonce: client-generated number used once
qop: quality of protection ("auth")
method: typically one of "GET", "POST", "PUT", etc.

HA1 = MD5(username:realm:password)
HA2 = MD5(method:digestURI)
response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)

The HA1 value is stored in the database as the password hash value. During authentication, the client calculates the value of response from the WWW-authenticate http headers. The server also calculates the response value using its stored version of HA1 and compares the value received from the client. If they are equal, the client is authenticated.

MD5 is no longer considered secure. Collisions can be found in a few hours using commodity hardware.

Using PBKDF2 to Strengthen Digest

  • Client obtains the username and plaintext password from the user.
  • Client requests the salt and iteration count for the user_id from the server. The server also sends the current default iteration count (which may be different than that used for this user).
  • Client calculates a 128-bit secret key using PBKDF2(password, salt, user-specific iteration count). The secret key is encoded as a hexadecimal string.
  • Client calculates HA1 using the username, realm, and hexadecimal-encoded key. This HA1 value is used in a standard digest authentication.
  • Server obtains the password hash from the database. The password hash is the previously calculated HA1 using the same PBKDF2-derived secret key. The server compares the calculated response to the response value sent by the client (standard digest authentication). If the two response values are equal, the client is authenticated.
  • If the user-specific iteration count returned to the client is different than the default iteration count, the client calculates a new HA1 using PBKDF2 and the new iteration count. The client calls a PUT method on the REST Server to update the password hash column using the new value. This step allows the algorithm to be updated with larger iteration counts as hardware get faster.

The modified algorithm does not rely on the strength of MD5 to protect the password hash, since the difficulty of calculating the password hash is dependent on PBKDF2 (which can use a SHA-1 or SHA-256 hash).

Are there any obvious security flaws in this modified algorithm?

  • Are you a cryptographer? – Lucas Kauffman Mar 6 '13 at 17:58
  • No. Not professionally. Just an interested amateur. – Ralph Mar 6 '13 at 18:21
  • 1
    Okay, just watch out with rolling your own :) – Lucas Kauffman Mar 6 '13 at 18:39

PBKDF2 is a burden. That's the whole point. The thousands of iterations, by design, burn up massive amounts of CPU.

Apart from that, your scheme is indeed an upgrade over plain Digest authentication, but it does not fix everything. In particular, what the server stores (the HA1 value) is "password equivalent": if you know this value, you can use it to connect to the server and play the authentication game. This means that if an attacker hacks into the server and steals a copy of the stored "passwords", then he gains immediate access to all accounts (i.e. the attacker transforms a partial read-only peek at the table, e.g. with a SQL injection attack or a mislaid backup tape, into a complete read-write access). That's usually considered as bad. Plain digest authentication already has this problem, because the server must store the password "as is". Your use of PBKDF2 does not fix that.

In any case, I hope that you play this protocol within SSL (HTTPS), because otherwise your connections can just be hijacked. And if you do play the protocol within SSL, then you can use Basic authentication, which will be even simpler for clients, and allows the server to apply PBKDF2 itself, and store the resulting hash which is not password equivalent.

  • Good point about stealing the HA1 values from the database. I'll have to rethink using BASIC authentication with a calculation of the PBKDF2 value on the server. Yes to SSL/TLS. – Ralph Mar 6 '13 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.