Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

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.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

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").

share|improve this answer
    
Brilliant thank you! That's very well explained, and makes sense. –  Thomas Clayson Mar 24 '13 at 11:46
add comment

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.

share|improve this answer
    
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. –  Thomas Clayson Mar 24 '13 at 11:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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