Luca Schneider

Understanding TOTP: Time-based One-Time Passwords

What is TOTP?

TOTP is an extension of the HMAC-based One-Time Password (HOTP) algorithm. It combines a secret key with the current time to generate a unique, short-lived password. This time-based approach adds an extra layer of security by ensuring that each password is valid only for a limited time.

Generator

0000

Explanation: How TOTP Works

Secret key

TOTP has a few steps to generate the one-time password. The first step is to get a secret. This secret is a shared secret between the server and the client. The secret is usually generated by the server and displayed as a QR code to the user. The user can then scan the QR code with an authenticator app and the secret is stored in the app.

Afterwards the secret key is converted to base32 or directly created as base32 and shared between the server and the client.

GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ

This is the standard encoding for TOTP and also recommended in the RFC but in theory any shared form would work because in order to work with, it needs to be converted into the binary representation.

0000

Time

That is the first part of the input. For the second part we need the (T)ime in TOTP expressed in seconds since the Unix epoch. For another layer of obscurity we can change the starting value (offset) of the time calculation and determine for how long (time step) the current TOTP code should be valid. The resulting time value is calculated by subtracting the offset and dividing the result by the time step.

0

-

/

=

0

And as before, the time is converted to bytes. This is done by converting the number to a 64 bit big endian integer.

0000

Hashing

With both parts of the input ready, the next step is to hash the input. For that the two input parts are byte-wise concatenated before the hash function is applied.

0000

After the input is ready, the next step is to hash the input with one of three algorithms.

0000

If you played with the algorithm, you might have noticed that the output lenght is different for each algorithm but the TOTP output is a fixed sized output. Luckily the process accounts for these differences with the next steps.

Truncation

After we have generated the hashed output the next step is to get a number that is exactly 31 bits long (4 bytes with the highest bit set to 0) to not fall into the signness trap of numbers. This number can represent values from 0 to 2'147'483'647, which is enough to cover the six up to eight digits of the TOTP output.

To make the predictability of the output a bit better, the output of the hashing function is not directly truncated and converted to a number. Instead the last 4 bits of the last byte are used to determine the offset of the bytes that are used to create the number. This value can be between 0 and 15. Afterwards the bytes from the highest bit after the offset are taken and put into a 32 bit integer.

0

->

0000

by

=

0000

Afterwards and also the last step is to truncate the number again to the desired number of digits. This is done by taking the lowest digits (base10) of the number. And there you have it. The TOTP is generated and can be used to verify the user.

0000