90

After reading Part I of Ross Anderson's book, Security Engineering, and clarifying some topics on Wikipedia, I came across the idea of Client Nonce (cnonce). Ross never mentions it in his book and I'm struggling to understand the purpose it serves in user authentication.

A normal nonce is used to avoid replay attacks which involve using an expired response to gain privileges. The server provides the client with a nonce (Number used ONCE) which the client is forced to use to hash its response, the server then hashes the response it expects with the nonce it provided and if the hash of the client matches the hash of the server then the server can verify that the request is valid and fresh. This is all it verifies; valid and fresh.

The explanations I've found for a client nonce however are less straight forward and questionable. The Wikipedia page for digest access authentication and several responses here on Stack Overflow seem to suggest that a client nonce is used to avoid chosen-plaintext attacks. I have several problems with this idea:

  • If a person can sniff and insert packets, the greatest vulnerability is a man-in-the-middle attack which neither a nonce nor a cnonce can overcome, therefore making both meaningless.
  • Assuming for a second that the attacker doesn't want to engage in a man-in-the-middle attack and wants to recover the authentication details, how does a cnonce provide additional protection? If the attacker intercepts communication and replies to a request with its own nonce, then the response from the client will be a hash of the nonce, data and cnonce in addition to the cnonce in unencrypted form. Now the attacker has access to the nonce, cnonce and the hash. The attacker can now hash its rainbow tables with the nonce and cnonce and find a match. Therefore the cnonce provides zero additional protection.

So what is the purpose of a cnonce?

I assume there is some part of the equation I'm not understanding but I haven't yet found an explanation for what that part is.

EDIT Some answers have suggested that the client can provide a nonce and it will serve the same purpose. This breaks the challenge-response model however, what are the implications of this?

Xander
  • 35,525
  • 27
  • 113
  • 141
user2014
  • 1,003
  • 1
  • 8
  • 6

4 Answers4

148

A nonce is a unique value chosen by an entity in a protocol, and it is used to protect that entity against attacks which fall under the very large umbrella of "replay".

For instance, consider a password-based authentication protocol which goes like this:

  • server sends a "challenge" (a supposedly random value c) to the client
  • client shall respond by sending h(c || p) where h is a secure hash function (e.g. SHA-256), p is the user password, and '||' denotes concatenation
  • server looks up the password in its own database, recomputes the expected client response, and sees if it matches what the client sent

Passwords are secret values which fits in human brains; as such, they cannot be very complex, and it is possible to build a big dictionary which will contain the user password with high probability. By "big" I mean "can be enumerated with a medium-scale cluster in a few weeks". For the current discussion, we accept than an attacker will be able to break a single password by spending a few weeks of computation; this is the security level that we want to achieve.

Imagine a passive attacker: the attacker eavesdrops but does not alter the messages. He sees c and h(c || p), so he can use his cluster to enumerate potential passwords until a match is found. This will be expensive for him. If the attacker wants to attack two passwords then he must do the job twice. The attacker would like to have a bit of cost sharing between the two attack instances, using precomputed tables ("rainbow tables" are just a kind of precomputed table with optimized storage; but building a rainbow table still requires enumerating the complete dictionary and hashing each password). However, the random challenge defeats the attacker: since each instance involves a new challenge, the hash function input will be different for every session, even if the same password is used. Thus, the attacker cannot build useful precomputed tables, in particular rainbow tables.

Now suppose that the attacker becomes active. Instead of simply observing the messages, he will actively alter messages, dropping some, duplicating others, or inserting messages of its own. The attacker can now intercept a connection attempt from the client. The attacker chooses and sends his own challenge (c') and waits for the client response (h(c' || p)). Note that the true server is not contacted; the attacker just drops the connection abruptly immediately after the client response, so as to simulate a benign network error. In this attack model, the attacker has made a big improvement: he still has a challenge c' and the corresponding response, but the challenge is a value that the attacker has chosen as he saw fit. What the attacker will do is always server the same challenge c'. Using the same challenge every time allows the attacker to perform precomputations: he can build precomputed tables (i.e. rainbow tables) which use that special "challenge". Now the attacker can attack several distinct passwords without incurring the dictionary-enumeration cost for each.

A client nonce avoids this issue. The protocol becomes:

  • server sends a random challenge c
  • client chooses a nonce n (should be distinct every time)
  • client sends n || h(c || n || p)
  • server recomputes h(c || n || p) (using the p from its database) and sees if this value matches what the client sent

Since the client includes a new random value (the "nonce") in the hash function input for each session, the hash function input will be distinct every time, even if the attacker can choose the challenge. This defeats precomputed (rainbow) tables and restores our intended security level.

A crude emulation of a unique nonce is the user name. Two distinct users within the same system will have distinct names. However, the user will keep his name when he changes his password; and two distinct users may have the same name on two distinct systems (e.g. every Unix-like system has a "root" user). So the user name is not a good nonce (but it is still better than having no client nonce at all).

To sum up, the client nonce is about protecting the client from a replay attack (the "server" being in fact an attacker, who will send the same challenge to every client he wishes to attack). This is not needed if the challenge is executed over a channel which includes strong server authentication (such as SSL). Password Authenticated Key Exchange are advanced protocols which ensure mutual password-based authentication between client and server, without needing some a priori trust (the "root certificates" when a SSL client authenticates the SSL server certificate) and protecting against active and passive attackers (including the "cluster-for-two-weeks" attack on a single password, so that's strictly better than the protocol above, nonce or no nonce).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 3
    Wow. Thank you! I wish I could up vote this again. – user2014 Apr 11 '11 at 13:14
  • In digest authentication the server sends a nonce and then the client sends that same nonce back. Seems to me that a client nonce is only really useful where the server is taking what the client says is the nonce at face value instead of what the server, itself, generated? If the HTTP connection was keep-alive it seems to me that the server could know what the nonce it just sent was. – paynes_bay Jul 10 '11 at 23:30
  • 2
    @paynes_bay Statelessness often is a desirable property when using HTTP, especially for reasons of scalability and high availability. Not sending the nonce back to the server would make Digest Authentication stateful. – Evgeniy Berezovsky Oct 02 '12 at 01:37
  • Out of curiousity - is it an important component of the client nonce that the server tracks and records each such that authentication is rejected when a client nonce is also reused? – razzed May 31 '16 at 19:54
  • Just to make it clear: Client nonce is particularly for in case the attacker is the server, right? Otherwise, even if I am over a secure channel, someone/interceptor still simply forward the request again (replay) without having to decrypt it. But for such sort of attacks, we use other mechanisms, like a request counter (per nonce) and such. – zgulser Dec 24 '19 at 10:36
7

Let me try to respond to the meat of your question: "Assuming for a second that the attacker doesn't want to engage in a man-in-the-middle attack and wants to recover the authentication details, how does a cnonce provide additional protection?"

Typically a client not only includes a nonce with the request, but signs the entire request, including the nonce. This means that even if the attacker intercepts a message between client and server:

  1. A replay attack won't work (because the server is keeping track of the client nonces).
  2. The attacker can't just generate a new message with a new client nonce, because it doesn't know how to sign the new message appropriately (i.e. it lacks the client secret, or private key).
Bosh
  • 223
  • 1
  • 5
  • Doesn't a client produced nonce break the challenge-response model? What effect does this have? A cnonce can confirm that the message hasn't been seen before, but not that it's fresh. In other words, it opens the system up to timing attacks where an attacker intercepts the clients response, denies service, and reuses the response. –  Apr 10 '11 at 09:06
  • The client can include an expiration time. If the server receives the message after the expiration included in the (signed) message, it treats the message the same as if the signature were invalid. – yfeldblum Apr 11 '11 at 02:21
  • @Justice this introduces problems of synching time and so on. How does the server know what the time is on the client? This would be easy to spoof. – user2014 Apr 11 '11 at 02:23
  • 1
    A forger cannot spoof an expiration time because the expiration time is part of the message being signed. In HTTP, clock synchronization is not required because the client always gets clock times from the server; while the client may compute duration based on measuring its own clock, it will always add that duration to the clock time from the server to get another clock time. – yfeldblum Apr 11 '11 at 11:11
  • 1
    @Justice I just realised that using the server time and modifying it by client time is really just another way to implement a server nonce. So in actual fact using time in this way is simply just using a server nonce. – user2014 Apr 13 '11 at 06:54
  • I think "signing" here refers to some sort an authenticity stamp (like a HMAC or sth). – zgulser Feb 16 '20 at 08:48
1

I think a good idea would be to have a read about how the nonce value is used in something like Oauth. In short, when an application using OAuth makes a request to an OAuth-supported serve, the request has to contain a bunch of fields, two of which are timestamp and nonce. The purpose of the form is obvious: it gives an indication of the timeframe that the message was sent so that the server can make a better guess as to whether or not the message is stale. The latter is obviously a bunch of random characters/bytes.

When the entire OAuth header is hashed with the consumer secret, both of these fields are included. Then the has signature it appended to the request (whether it be query parameters or HTTP headers) and sent on to the server. The actual body of the request is not hashed.

The OAuth server should keep track of the previous set of N nonce values for a given client to make sure that they aren't reused. Given that the body of the message can change (essentially having no effect on the hash) it's important to have something else that will change (ie. the nonce) to make sure that requests are unique. Given the open/plain text nature of HTTP, this is pretty important.

Does this help clarify its purpose at all? (hope so :)).

OJ.
  • 371
  • 1
  • 5
  • 2
    Doesn't OAuth break the challenge-response model by having the consumer create the nonce? Isn't this bad? A user cnonce can confirm that the message hasn't been seen before, but not that it's fresh. In other words, it opens the system up to timing attacks where an attacker intercepts the clients response, denies service, and reuses the response. –  Apr 10 '11 at 09:02
1

According to RFC 2617, the cnonce and nc parameters protect against chosen plaintext attacks. How does this protect against such attacks?

If Eve changes the nonce the server sends to the client what has Eve gained? Eve can't generate h(password || nonce) from h(password || fake_nonce) and in theory it seems like the server shouldn't accept h(password || fake_nonce) anyway since the server should know what nonce's it's issued and what nonce's it hasn't.

paynes_bay
  • 181
  • 3
  • If you are asking a question, it should probably go in a separate question, rather than in an answer here. – D.W. Jul 11 '11 at 00:24
  • It's pretty much the same question that's being asked here. I want to know what the use of a client nonce is. RFC2617 provides an answer but that answer doesn't make a lot of sense to me. Thomas Pornin provided an answer as well but his answer doesn't make a lot of sense to me either per my response to his answer. – paynes_bay Jul 11 '11 at 01:27
  • @paynes_bay welcome to the site! Please read the [FAQ] - answers are for, well, *answering* the question. If you are looking for clarification on another answer, comments work. If you want additional information not covered by the original question, ask another! – AviD Jul 11 '11 at 22:48