2019 twenty-four merry days of Perl Feed

Two Factor Elfication

Authen::OATH - 2019-12-03

Day three.

Day three of piles of presents where there shouldn't be.

Day three of the hackers breaking into the North Pole systems.

Enough was enough. Yes, they'd compromised Pepper's account for the third day running, but Butters Jollycane was completely done with trying to get his hapless colleague to protect his password - it was a lost cause. Today was going to be the last day that anyone getting access to an Elf's password was going to allow them access to all of the North Pole systems. Jollycane was going to configure their system for Two-Factor Authentication.

2FA

Two Factor Authentication simply means that you have a second factor that you use for authentication. Typical factors include things that you know (passwords, security questions,) things that you have (dongles or apps that create unguessable time-based sequences) or things that you are (biometrics.)

Jollycane wasn't able to add finger print or retinal scanners for the elves, so he was going to have to rely on the elves having something they knew (their password) and something they had.

By My OATH They Won't Get In

Jollycane needed a solution that he could implement in the next few hours. No time to ship devices to all the elves. He'd have them make use of their company issued cell phones for now.

Google Authenticator is one of many smart-phone apps that implement the One Time Password algorithms as defined by the open OATH specification in order to act as a second factor. In short, every thirty seconds the app displays a new six digit code which the user has to enter when logging in in addition to the password.

toph

There's a shared secret known only to the website and the authenticator app. Both the app and the server run the same algorithm based upon the current time and the shared secret. If the code the user copies from their phone matches the server's expected value then authentication occurs.

use Authen::OATH ();
use Convert::Base32 qw( decode_base32 );

my $oath = Authen::OATH->new;
my $secret = 'mySecret';
my $otp = $oath->totp( decode_base32( $secret ) );

if ($the_code_the_user_entered eq $otp) {
    say "ACCESS GRANTED";
} else {
    say "HACKER ALERT WHOOP WHOOP";
}

Passing Secrets

Jollycane needed a way to allow his elves to configure their authenticator apps. The most common way to do this is to create a QR code (a "2d barcode") that uses the otpauth url scheme. Google Authenticator allows users to "scan" this QR code with their phone's camera.

qr scan

Crating these in Perl is actually quite straight forward once you know the format the URL should be in

my $qrcode = HTML::QRCode->new;
my $html = $qrcode->plot(
    'otpauth://totp/' # URI standard
    . 'pfrostyflakes@northpole.example.com' # label
    . '?secret='. decode_base32( $secret ) # secret
    . '&issuer=North+Pole' # issuer
);

This outputs a bunch of HTML that when rended by a browser looks like:

Hopefully that would be good enough to finally keep these kids out!

Gravatar Image This article contributed by: Mark Fowler <mark@twoshortplanks.com>