2

In a HTTP scheme where the HMAC-SHA256 signature is sent as part of the Authorization header, and the message input contains:

  • The request method
  • URL
  • Post data
  • Nonce
  • Date HTTP header

How unique does the nonce need to be, or, for how long should the nonce be disallowed to be re-used?

For example, if I enforce uniqueness of (Date, nonce) rather than enforcing absolute uniqueness of the nonce on its own, have I introduced any weakness to replay or other kinds of attack?

When another second of time elapses, the signature changes (due to the Date header), so if I re-use a nonce from 1 second ago, it should not be a problem, right?

2
  • Is this a custom authentication system or is it a part of some Digest scheme? Commented Dec 20, 2014 at 23:46
  • @sebastiannielsen it is custom authentication, not dissimilar to restcookbook.com/Basics/loggingin
    – az_
    Commented Dec 20, 2014 at 23:53

2 Answers 2

2

You need to take in consideration the allowable time window (to compensate for Clock drift). If you allow Date's with a time window of plus/minus 10 minutes (total: 20 minutes) you need to use nonces that are unique on the whole time window, and you also need to store spent nonces from that time period.

To avoid a race situation where a nonce is being deleted from the "spent" list Before the Date: header of the used nonce has became invalid, it would be recommended to store the spent nonces from the last 40 minutes, and also use nonces that are unique for 40 minutes.

Then you have a practically a watertight solution.

In other Words, if you would allow a nonce to be reused after 1 second, a attacker can just resend the old request with the old date header, since if you allow a time window - which you must because you cannot ensure the client Clock is synced with the server, then you would accept a request with a spent nonce.

If you reallywant a good nonce, use H(Time, Nonce) where H is a decent hash function. Then you can use "non-unique" nonces as long as you dont generate 2 equal nonces the same second. Then you get unique hashes to use as nonces.

2
  • Is there a guideline or way of figuring out what an acceptable clock drift tolerance is? Something that may be relevant - some clients will be mobile clients. Obviously I'd want it as low as possible to limit the number of nonces I need to keep track of.
    – az_
    Commented Dec 21, 2014 at 2:23
  • 2
    If you are gonna go for the type of authentication where the client will be required to do a blank request and get a 401 first, you could have that the server supplies a random nonce that the client should use that is valid for lets say 5-10 minutes. Then you can use a database with positive authentication instead, where VALID nonces are specified and everyelse is invalid. However, if you want to run a instant authentication scheme, I would suggest plus/minus 10 minutes, which would give 40 minutes to keep track of including the safety margin. Commented Dec 21, 2014 at 2:31
2

I don't mean to be blunt, but as you're inventing your own authentication algorithm, you'll almost certainly mess it up and it will be subject to many types of attacks. I strongly suggest you study the available research papers and known cryptographic authentication algorithms before you create your own so that you know what mistakes to not make. Start with Kerberos authentication, then Zero Knowledge Proofs, then SSL/PKI.

That said, to answer your question, both the client and the server should generate nonces that are likely (or guaranteed) to be used once for your time window. Nonces are to be used Once (number once). A sufficiently large random number serves that purpose and need not be stored. Having both client and server generate a nonce (2 different nonces) means that both reduce the chance of a replay attack from the other side.

In addition, you don't want your authentication server to become an Oracle (assist an attacking client with guessing user passwords) or a spoofed server breaking user passwords (trick a client into revealing it's password), so you need to be careful how you design your algorithm. The minimum number of steps required for an authentication algorithm is four.

  1. c-s: hello, I'm client + nonce_c.
  2. s-c: client-challenge + nonce_s.
  3. c-s: client-response + server-challenge.
  4. server-response.

See the above algorithm? Client says who it is (Step 1) which includes the client nonce, then (Step 2) server asks client to prove something the server generated using both the client's nonce, a stored client authenticator (password hash, for example) and a server generated nonce. Step 3 proves the client to the server. Step 4 (which most people forget) proves the server to the client; an important step to protect your clients from spoofed server attacks (man in the middle and dns spoofing).

With this type of algorithm, you need not store nonces or worry about reusing them within some time window. Instead, make them sufficiently large and random - together the client and server participate in the creation of a nonce with sufficiently secure properties.

9
  • No, you did get it wrong. If you want to have server spoofing prevention, you must perform the server validation step Before client validation step. Your scheme could be easly MITMed by having a MITM perform step 1-3 alongside with client, and then ignore the server-response. Even if the spoofed server would send a fraudulent server response and the client would notice this, its too late. Any server validation must happen BEFORE authentication, so client can refuse to authenticate if the server identity cannot be verified. Commented Dec 22, 2014 at 16:18
  • In this case, the server could just pretend to lose Connection instead of sending a fraudulent server-response, and the client will Think "its just a congested network or bad phone coverage now" when its infact is talking with a spoofed server. Commented Dec 22, 2014 at 16:20
  • @sebastiannielsen, apologies, but I'm confused. The objective of a properly built authn protocol is to produce a session key used to protect the channel. If the channel is not encrypted or signed (clear, but hashed), then that is a problem. In the common internet model, you might be thinking of SSL server-side only authentication with client password authn inside the SSL channel. However, this is a flawed authentication protocol as the server and client authns may be separated and attacked - a flaw in almost all current schemes. I stand by my statement; the familiar use case is insecure. Commented Dec 23, 2014 at 8:24
  • On a more practical note, how do you propose to authenticate the server first? Commented Dec 23, 2014 at 8:49
  • Assuming the server and client has shared a secret previously, you just make sure client sends their challenge first, server must reply correctly to client challenge Before client will respond to server's challenge. You still will be vulnerable to MITM, but if the transfer channel is part of authentication (eg, signed in some way with a HMAC) then the MITM can only passively Watch the transaction without modifying anything. Server-response and client-challenge can be the same string of charachters. Commented Dec 24, 2014 at 4:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .