How to implement 2-factor authentication with Google Authenticator using php library -PHPGangsta

Lonare
6 min readMar 11, 2020

--

Many major web services now offer 2-factor authentication, PayPal, Amazon, Facebook and not least Google. With 2-factor authentication, a one-time password, a so-called one-time token, must be entered in addition to the user name and password, which is generated by a device independently of the PC and is only valid once. So if someone can do it and guess or record the password, it doesn’t help the attacker because he also has to have access to the hardware device, and that should be difficult.

The generation of such codes is not particularly difficult, both parties (the device and the website) only need to know a common “shared secret” (also called a seed), and based on this then can always generate changing codes. There are RFCs, for example RFC 4226.

Today I would like to introduce the Google Authenticator and show how you can extend your own website with this 2-factor login using PHP.

The Google Authenticator is designed as an app for cell phones, so you don’t have to buy hardware, just install an app, the Google Authenticator is available for Android, IPhone / iPad, Blackberry and other platforms. There are also implementations for Windows, Java and Palm OS . It is open source.

The installation of the Google Authenticator is very easy and can be found on Google. Usually this is very easy via the Market / AppStore.

There are some PHP implementations out there, but I wanted to have my own ;-). And I built a class ( GoogleAuthenticator on Github ) that can do everything I need:

  1. Generate a new secret
  2. Calculate the current code for a given secret
  3. Check a code for a given secret (including variable time deviation tolerance)
  4. Return a QR code URL for a QR code image for a given secret

Step 1# How to install

Simple composer command to install this liberary. Obviously its not the normal composer command because there is no official release.

I think there is no available the 1.0.1 version from the package.

When you run the composer show --available phpgangsta/googleauthenticator command then you can see there the possible versions but there is only the dev-master.

And this version is not a stable version. Composer wants to install only stable versions from packages defaultly, but there is not.

So if you want to use this in your project then need to install with composer require --prefer-dist phpgangsta/googleauthenticator:dev-master command.

composer require --prefer-dist phpgangsta/googleauthenticator:dev-master

composer install

  1. Composerwill take care of autoloading the library. Just include the following at the top of your filerequire_once __DIR__ . '/../vendor/autoload.php';
  2. This is what I have used in my codeignitor application
    require_once(APPPATH.'third_party/PHPGangsta/vendor/autoload.php');

Step 2# First line of code

created a page to activate it for your users:

//echo $_SESSION['USERID'];

$ga = new PHPGangsta_GoogleAuthenticator();

$secret = $ga->createSecret();

$gcode = $this->input->post('google_code');

$qrCodeUrl = $ga->getQRCodeGoogleUrl(SITENAME, $secret);

$data['QRCODE_IMG'] = $qrCodeUrl;

$this->view->load('YOUR_VIEW', $data);

This above code should look something like this on your website:

Two Factor Authentication Setup Page

Step 3# Verify the code

This is how you get the code from user and verify it

$user = $this->Entity_model->get($userid);

$ga = new PHPGangsta_GoogleAuthenticator();

$gcode = $this->input->post('google_code');

$ga = new PHPGangsta_GoogleAuthenticator();

$checkResult = $ga->verifyCode($user->TWO_FACTOR_SECRET, $gcode, 2); // 2 = 2*30sec clock tolerance

if ($checkResult) {

return true;

return false;

After verification you can show your users success message.

Step 4# Initiate login with two actor for your users

After they log in with their email and password redirect them to your two factor authentication page

$gcode = $this->input->post('google_code');

$ga = new PHPGangsta_GoogleAuthenticator();

$user = $this->Entity_model->get($USERID);

$checkResult = $ga->verifyCode($user->TWO_FACTOR_SECRET, $gcode, 2);

if ($checkResult) {

$_SESSION['IS_LOGGED'] = true;

redirect('dashboard');

$data['error'] = "We are not able to verify your code. Please try again.";

First user will login into his/her account:

Tow factor login window

Then you can redirect user to the verification window:

$gcode = $this->input->post('google_code');

$ga = new PHPGangsta_GoogleAuthenticator();

$user = $this->Entity_model->get($USERID);

$checkResult = $ga->verifyCode($user->TWO_FACTOR_SECRET, $gcode, 2);

if ($checkResult)

{

$_SESSION['IS_LOGGED'] = true;

redirect('dashboard');

}else{

$data['error'] = "We are not able to verify your code. Please try again.";

}

Two factor verification window

If user provide wrong authentication code then you can show them errors:

Two factor authentication error page

The website now generates a secret for a customer on request, stores it in a database, and then either presents the customer directly with the secret that he then has to type, or shows him the QR code that contains the secret. This QR code can be easily scanned with the Google Authenticator and codes are displayed on the cell phone.

The website must of course display another form (field) for an activated user when logging in, in which a valid code must be entered. If this was valid, it must be saved and must not be used again, otherwise a listener could use it in the next few seconds and log in with it. After a few minutes (depending on the tolerance limit setting), these old used codes can be deleted.

Secret / Seed: OQB6ZZGYHCPSX4AK

Depending on the security level, the code must be entered each time you log in, or a cookie is saved so that the code only has to be entered every X days. On a new PC or in another browser, the code is of course needed again at the beginning. Depending on how safe or convenient you want it to be.The whole thing can be offered optionally, so that only users who have set it up can use it or make it mandatory for all users. Here too it depends on the security strategy of the site / company.

Possible pitfalls or important things to think about:

  1. Time synchronization is important when implementing the Google Authenticator. The clocks of server and client must not be too far apart, otherwise authentication will always fail. For this reason, you should not only offer the standard allowed 30 seconds tolerance, but possibly 1:30 or 4:00 minutes. To do this, the server simply calculates the previous and next codes and takes them all for comparison.
  2. As already mentioned above, replay attacks must be avoided. Once used, codes have to be blacklisted for the user so that they cannot be used again in the next few minutes.
  3. In general, of course, protection against brute force also applies here. If you take 6 characters in length like Google, these are not too many options that you should try out. You have to limit the number of attempts per minute.
  4. If the cell phone is lost or stolen, you should of course still be able to log into the account and revoke the secret. To do this, you can either set up the Google Authenticator on a replacement cell phone a second time, or set other ways such as emergency codes, specify a friend’s cell phone to have a new password sent to you by SMS.

An interesting page to play around with the Secret, the QR code and the code is this Javascript implementation

Originally published at https://www.blognow.org.

--

--

Lonare
Lonare

Written by Lonare

Imagination is the key to unlock the world. I am trying to unlock mine.

Responses (1)