Working:
Authenticator implements the Time-Based One-Time Password (TOTP) algorithm. It has the following ingredients:
• A shared secret (a sequence of bytes)
• An input derived from the current time
• A signing function
Shared Secret :
The shared secret is what you need to obtain to set up the account on your phone. Either you take a photo of a QR code using your phone or you can enter the secret manually.
Input (Current Time) :
The input time value you'll simply get from your phone, no further interaction with the server is required once you have obtained the secret. However it is important that your phone's time is accurate as the server will essentially repeat what happens on your phone using the current time as known by the server.
Signing Function :
The signing function used is HMAC-SHA1. HMAC stands for Hash-based message authentication code and it is an algorithm that uses a secure one-way hash function (SHA1 in this case) to sign a value. Using an HMAC allows us to verify authenticity - only people knowing the secret can generate the same output for the same input (the current time).
OTP Algorithm:
Pseudo Code:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30 // sets a constant value for 30 seconds
hmac = SHA1(secret + SHA1(secret + input)) //apply hashing
offset = hmac[len(hmac)-1] & 0x0F //Last nibble
four_bytes = hmac[offset : offset+4] //takes a subset of 4 bytes from 20 bytes
large_integer = INT(four_bytes) //Covert four bytes to integer
small_integer = large_integer % 1,000,00 //gives 6 digit code
Reference: https://garbagecollected.org/2014/09/14/how-google-authenticator-works/
Also check out this github project for GO implementation:
https://github.com/robbiev/two-factor-auth/blob/master/main.go