Time-based One Time Password Algorithm

Follow the algorithm

As implemented in Google Authenticator app, you’ll need:

  • A shared secret key K, which is base32 encoded
  • a specific time period since UNIX epoch T

I’ll use K = GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ and T = 1450235092 (which is Wed, 16 Dec 2015 11:04:52 CST) for example. In the Google Authenticator App, both K and T are passed to TOTP as hexadecimal values (or byte arrays).

Since K is a base32 encoded string, we’ll decode it to byte format. Password changes every 30 seconds, T should be divided by 30, tuncated to integer and converted to hex and padded to 16 hexadecimal digits.

K     = 12345678901234567890
K_hex = 31 21 33 34 35 36 37 38 39 30 31 21 33 34 35 36 37 38 39 30
T     = truncate(1450235092/30) = 48341169
T_hex = 00 00 00 00 02 E1 A0 B1

The core of TOTP is a hmac-sha1 function, say mac_value = hmac-sha1(auth_code, content). We use K_hex as the auth_code and T_hex as the content.

Byte:       1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20
mac_value = 3d 43 cb 58 89 39 a1 a4 bf 76 b9 dc 27 79 81 70 f7 22 a5 0c

Now we need an offset offset = last 4 bits of mac_value

Byte:       1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20
mac_value = 3d 43 cb 58 89 39 a1 a4 bf 76 b9 dc 27 79 81 70 f7 22 a5 0c
                                                        offset = 12   ^

And cut off 4 bytes from offset number of bytes to get an intermediate value IV1

Byte:       1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20
mac_value = 3d 43 cb 58 89 39 a1 a4 bf 76 b9 dc 27 79 81 70 f7 22 a5 0c
IV1       = ** ** ** ** ** ** ** ** ** ** ** ** 27 79 81 70 ** ** ** **

In case that big endian and little endian would interfere with generation, mask IV1 with 0x7FFFFFFF

IV1       = 27 79 81 70
mask      = 7F FF FF FF
IV2       = 27 79 81 70

then pick last 6 digits of IV2

IV2       = 662274416
Token     = ***274416

So at Wed, 16 Dec 2015 11:04:52 CST, with the key GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ, you get the token 274416.

Full implementation

see my GitHub repository cthbleachbit/totp-cth-cli, a bash implementation of a TOTP password manager, I used openssl for hmac hashing and database encryption.

Reference

Leave a Reply

Your email address will not be published. Required fields are marked *