I have an interesting case regarding protection against replay attacks. Under the assumption that Alice and Bob have used Diffie-Hellman key exchange to establish a secure temporary session, would it be safe for them to use the public portion of their DH keys as nonce seeders in combination with HMAC to protect from replay attacks? In pseudo code -

Establishing a session:

    (dhA, dhSecret) = DH_GEN(common)
    a->b (dhA)

    (dhB, dhSecret) = DH_GEN(common)
    b->a (dhB)

    a<-b (dhB)
    sessionKey = DH_KEY(dhB, dhSecret)

    b<-a (dhA)
    sessionKey = DH_KEY(dhA, dhSecret)

Now when Alice wants to send some data to Bob:

    data = ENCRYPT(sessionKey, data)
    hmac = HMAC(sessionKey, data | dhA)
    a->b (data, hmac)

And on Bob's side the process is reversed:

    b<-a (data, hmac)
    if (hmac == HMAC(sessionKey, data | dhA+1)) {
        data = DECRYPT(sessionKey, data)

The same thing happens in the opposite direction:

    data = ENCRYPT(sessionKey, data)
    hmac = HMAC(sessionKey, data | dhB)
    b->a (data, hmac)

    a<-b (data, hmac)
    if (hmac == HMAC(sessionKey, data | dhB+1)) {
        data = DECRYPT(sessionKey, data)

And the second question - would it be easier and just as safe to use a self-incrementing nonce starting from a fixed number (say 0) instead of using fairly large DH public keys for the initial nonce?

What are the perils (if any) of such approach, aside from a possible MITM attack during the session establishment which can be thwarted using some form of authenticated Diffie-Hellman KE (e.g. having the generated public keys signed by trusted certificates during the exchange)?


2 Answers 2


A nonce is a "number used once".

This is question is asking "should I use a the same value for my nonce each time". The answer is no.

Start with a number which is not predictable, e.g. from a good random source.

Edit 2: You gave the answer yourself. The nonce need not be kept secret. But the DH shared key must be. If you use the key for the nonce you will then need to keep the nonce secret...

Edit: I think what we have here is that nobody has ever considered the question, in the same way as nobody has ever asked "is it safe to clean my teeth with the polishing bit on a dremel". Spending any time thinking about the question is a waste of time.

  • To clean your teeth, use a toothbrush.
  • For a nonce, use a good random source.

Then get on with the next job.

Or, to be slightly less snarky, you need to ensure the number is only used once. A good random source achieves that statistically. Using e.g. the time remote IP achieves that physically. Neither of those uses information which must be kept secret.

  • I know what nonce stands for - that's why the 'nonces' in the above example auto-increase on each data transmission. I am asking about the nonce source and whether it is safe to use the public part of the DH key exchange process as a nonce seed given that those numbers are already pretty much random and that both Alice and Bob have already exchanged them during the session establishment process. AFAIK, the nonce need not to be private so I'm trying to find what other drawbacks might there be using this approach. Mar 6, 2014 at 13:21
  • Wait.. what? If you XOR the shared key with the randomness you now need to make really sure that randomness is never leaked out, otherwise you have a key-breach - and if you didn't trust your randomness before (e.g. it was predictable), now I can use that prediction to predict your key (by predicting the randomness and XORing it over your nonce to recover your key). Tl;dr: Don't put private keys or session keys anywhere close to data you're intending to put on the wire in plaintext.
    – Matt
    Apr 14, 2014 at 1:17
  • @matt, good point. Edited.
    – Ben
    Apr 14, 2014 at 9:30
  • What if you were to use Diffie hellman ephemeral?
    – hl3mukkel
    Jan 22, 2016 at 23:51
  • @hl3mukkel, what if you were to use a handgun to hammer in a nail? It'll probably work, won't it? A pistol is quite heavy, and made of metal. It has a lot in common with a hammer.
    – Ben
    Jan 22, 2016 at 23:52

To your second question - use a self incrementing nonce starting from 0 (for example), should a nonce ideally not be hard to guess? A linearly incrementing nonce is, by nature, predictable.

  • As a rule of thumb, and to best of my knowledge, yes - but in this particular instance the nonce is used just during the HMAC generation to ensure replay-proof operation. Given that the sessionKey is secret and under the assumption that the HMAC uses cryptographically safe hash, it is my understanding that it shouldn't matter what the nonce is as long as both parties can be certain of its value at any given point. Of course, I might be wrong, which is why I've decided to run the question over to you folks :) Mar 6, 2014 at 19:27

You must log in to answer this question.

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