Setting up Google Two-Factor Authentication

By Levi Clancy for לוי on
updated

▶︎ View related▼︎ Tap to hide

Two-factor authentication is a login system that requires the user to have a password they enter, plus a secret code from a device that they own. This means that even if a user's password is stolen or guessed, a hacker cannot log in without also having the user's device that has that secret code. This also works for DUO!

  • Google Authenticator is an app available for iOS and Android to support two-factor authentication. DUO also supports the same protocol in the same way.

  • The authenticator secret is a secret code stored on the server that is specific to the user and is also stored on their device.

  • The authenticator code is a time-sensitive six-digit code from the user's device that they use to verify their login elsewhere.

  • Base 32 encoding is a type of encoding used with the protocol.

The protocol used with Google Authenticator (and compatible with DUO) uses a custom algorithm that generates codes from the authenticator secret that are only valid for thirty seconds at a time.

Base 32 encoding

Base 32 encoding is a well-established standard that is great for web because it is all upper-case without confusing characters. It uses the 26 upper-case letters of the English alphabet, plus the numbers 2 - 7 (avoiding 1 that looks like I, and 0 that looks like O). This results in 32 possible characters. This is particularly important, because each binary number between 0 (0 in binary) to 31 (11111 in binary) can be mapped to a character. For example: the 0 (0 in binary) maps to the letter A, 1 (1 in binary) maps to the letter B, 2 (10 in binary) maps to C, and so forth. You get an alphabet map like this,

Decimal Binary Character

0

0

A

1

1

B

2

10

C

3

11

D

4

100

E

5

101

F

6

110

G

7

111

H

8

1000

I

9

1001

J

10

1010

K

11

1011

L

12

1100

M

13

1101

N

14

1110

O

15

1111

P

16

10000

Q

17

10001

R

18

10010

S

19

10011

T

20

10100

U

21

10101

V

22

10110

W

23

10111

X

24

11000

Y

25

11001

Z

26

11010

2

27

11011

3

28

11100

4

29

11101

5

30

11110

6

31

11111

7

Writing a function that can convert any string to base 32 encoding works like this,

  1. Split the string into individual characters: LOVE is split into 'L', 'O', 'V', 'E'.

  2. Convert each character into its eight-digit ASCII binary equivalent. Languages will generally have this functionality built-in. LOVE becomes '01001100', '01001111', '01010110', '01000101'.

  3. Merge the binary equivalents into one long string of numbers. LOVE becomes '01001100010011110101011001000101' with leading zeroes preserved.

  4. Split the long binary string into chunks of five digits each, and add zeroes to the last chunk if it is not long enough. LOVE becomes '01001', '10001', '00111', '10101', '01100', '10001', '01000'.

  5. Now convert each chunk use the base 32 character map from its five-digit binary number to a character equivalent. LOVE thus becomes 'J', 'R', 'H', 'V', 'M', 'R', 'I'.

PHP code sample,

Authenticator secret

Write an authenticator secret that uses the same character map as the base 32 set. Although you can take any secret and encode it into base 32, my recommendation is to stick to the protocol. Frankly, the user should never see this code.

Authenticator code

Google designed an excellent algorithm to generate six-digit codes valid for thirty seconds each, for use in two-factor authentication.
  1. Take the current UTC timestamp and divide it by thirty.

  2. Pack it into a binary string.

  3. SHA1 encode the time together with the authenticator secret.

  4. Use last bit as index/offset.

  5. Grab four bytes using that index/offset.

  6. Unpack the binary value.

  7. You want only a thirty-bit result

  8. Make sure that it is six characters.

PHP code sample,

QR code

At some point in user account generation and management, give them the tools they need to add their authenticator secret to their device. This is usually done via a QR code of an app link but can also be achieved via a direct app link.

Authentication flow

When the user logs in, make sure to have them enter the six-digit code off their device. Generate a six-digit code server-side and double-check that they match in order to have used two-factor authentication on their login.

Studies