7

I thought about "recovering", "determining", "guessing", "calculating" or "reproducing" the HOTP/TOTP secrets when only the outcome (6-digit code + time) is known.

In case we can view the live creation of HOTP/TOTP codes without knowing the actual secret.

  1. How many known results (combination of time and the 6-digit code) does it take in order to "guess" the secret key?
  2. And so, how likely is it that we can successfully recover the secret key in order to reuse it and validate the produced output?
  3. Are there (code) examples of how this could be achieved?
Bob Ortiz
  • 6,234
  • 8
  • 43
  • 90
  • I would expect TOTP/HOTP to be hardened against this (which is essentially a known plaintext attack), so I would assume knowing previous numbers would give you no advantage over pure bruteforce. – André Borie Jun 20 '17 at 09:41

2 Answers2

6

Have a look how the HOTP (TOTP is just a special case based on a time for now) is calculated. It is using HMAC based on hash function either SHA1, SHA2 (or MD5 in worst security case) of secret seed and some counter. It is returning some part of the result as a PIN.

As an attacked intercepting the PINs, you are trying to find out a secret seed of unknown length.

Based on the definition of hash function, it not reversible (unless it is broken). You can not simply reverse the operation even if you would have the whole hash. But you have 6 to 8 decimal numbers. You also do not know where they fit into longer decimal string -- this is also changing based on last byte).

So what are the options you have? The easiest way would probably be to brute-force all the possible values for seed (for example 32 B hexadecimal string) and compare them with the intercepted data. This could work with the TOTP since you can know also the time when it was generated (30s time frames). But in the HOTP, you have no idea what the counter is (unless you would manage to intercept all the PINs.

I would say, the strength of the OTP is its complexity of the algorithm and simplicity of use. I am not giving a proof why it is hard, but I hope the answer summed your question and answers why you can not simply do that.

Jakuje
  • 5,229
  • 16
  • 31
-1

A blog post I read had a step-by-step guide for bruteforcing a base32 encoded shared secret. The technique used only needed two OTP codes + time stamps, but I don't remember the details or if the codes had to be for consecutive time periods. I can't seem to find the post now, and I don't have it bookmarked - if anyone knows the post I'm talking about, please share!

Summarizing from memory, you need to enumerate (via brute force) many possible shared secrets that could have been used to generate each code. Comparing the two lists, you will see only one shared secret that could have generated both codes.

It's not possible to brute force a 128-bit secret, but (again, from memory) ambiguity in the standard and encoding quirks of base32 values means that most secrets are actually much shorter - enough to brute force. A base32-encoded secret with 16 characters, for example, is only 80 bits when decoded.

There may have been other optimizations to make the bruteforcing faster. I think I recall something about working backwards from the OTP codes to find portions of the secret's hash, and then using a Hashcat mask to quickly discard any candidate hash not matching the pattern. Or maybe rainbow tables were used. A lot of the finer details escape me, so I'd really like that link if anyone has it...