This is a clone of a question I posted on Stack Exchange. Thought I might catch the eye of some different people who could help here.

We are trying to implement a hmac-based one time password protocol for use authenticating users over our api.

The idea is to encrypt a unique identifier for the user (uid) against a private key and an incremental counter. Then increment the counter for the next call.

encrypt(uid, private_key, counter)
# now increment the counter for the next call

Then on the server side, decrypt using the private key and the counter to get the user identifier (uid).

decrypt(encrpyted_string, private_key, counter)
# now increment the counter for the next received request

This works fine. Each call is completely unique (one time) because of the counter.

However how would we handle synchronisation of the counter? What happens if the client generates a request, increments the counter for the next call, and sends the request, but the server is offline and never receives the request, or there is an internet connectivity issue and the request never gets through - now the server and the client are out of sync with each other's counters.

Is this a case of "you should know if a request has been submitted"? I.e. we could add a response header from the server to say whether the counter has been incremented and only if it has do we increment the counter in the app too... but then the same could be said the other way around - we could send a request, the server receives it, increments its own counter and sends a response, but the internet connection has been interrupted whilst the server was processing its request and the app never receives the response, never increments its counter and therefore the two are out of sync again.

Thanks for any insight you can give me.


2 Answers 2


See HOTP, section E.4. This is reasonably well explained. The gist of the solution: when the counter on the server contains n, the server actually accepts as valid the one-time passwords corresponding to values n, n+1, n+2... up to (say) n+99. If what the client sent matches the one-time password for value n+37, then the client is accepted, and the new counter value in the server is set to n+38. The width of the range accepted by the server is a trade-off: a larger range tolerates clients which are widely out of synch, but it is more expensive on the server side (more potential one-time passwords to compute) and decreases security (since more distinct passwords will, at any time, be deemed "acceptable").

  • Brilliant thank you! That's very well explained, and makes sense. Mar 24, 2013 at 11:46
  • Actually the link you sent to the RFC Appendix E talks about a slightly improved version of the described resync protocol. The client sends the password as well as the counter value corresponding to the password. The counter value has to fall within an allowable look-ahead window ahead of the server counter value. But the size of this window won't compromise security because the client has to know which counter the password corresponds to. May 17, 2021 at 17:34

Typically the solution for this is either to a) check it against the values going forward several to see if this occurred and increment accordingly if it is found to have drifted ahead. (This is how time based tokens account for clock drift.) or b) if the systems can interact, do an exchange of the current counter value on both systems. They can agree on whatever the latest used value is and use that. It is worth noting that without a time limitation however, replay will be possible as a phishing site could ask for the next code and then use it to talk to the server. A time based system would limit the window of opportunity for such an attack to ensure that the user is trying to get on at the time and would thus notice (hopefully) their legitimate session being rejected.

  • Thanks for this. Although we are aware of benefits of a time based system, our client has specifically asked for a hmac based system. I don't think we really want to be syncing over the connection either, as you say it makes it easier to attack if you can get the current counter value on request. Mar 24, 2013 at 11:48

You must log in to answer this question.

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