NAME
Authen::TOTP - Interface to RFC6238 two factor authentication (2FA)
Version 0.0.2
SYNOPSIS
use Authen::TOTP;
DESCRIPTION
Authen::TOTP
is a simple interface for creating and verifying RFC6238 OTPs as used by Google Authenticator, Authy, Duo Mobile etc
It currently passes RFC6238 Test Vectors for SHA1
USAGE
my $gen = new Authen::TOTP(
secret => "some_random_stuff",
);
#will generate a TOTP URI, suitable to use in a QR Code
my $uri = $gen->generate_otp(user => 'user\@example.com', issuer => "example.com");
print qq{$uri\n};
#store $gen->secret() someplace safe!
#use Imager::QRCode to plot the secret for the user
use Imager::QRCode;
my $qrcode = Imager::QRCode->new(
size => 4,
margin => 3,
level => 'L',
casesensitive => 1,
lightcolor => Imager::Color->new(255, 255, 255),
darkcolor => Imager::Color->new(0, 0, 0),
);
my $img = $qrcode->plot($uri);
$img->write(file => "totp.png", type => "png");
#...or you can pass it to google charts and be done with it
#compare user's OTP with computed one
if ($gen->validate_otp(otp => <user_input>, secret => <stored_secret>, tolerance => 1)) {
#2FA success
}
else {
#no match
}
new Authen::TOTP
my $gen = new Authen::TOTP(
digits => [6|8],
period => [30|60],
algorithm => "SHA1", #currently only this supported
secret => "some_random_stuff",
when => <some_epoch>,
tolerance => 0,
);
Parameters/Properties (defaults listed)
- digits
-
6
=> How many digits to produce/compare - period
-
30
=> OTP is valid for this many seconds - algorithm
-
SHA1
=> only SHA1 currently supported by the module as well as most (?) clients - secret
-
random_12byte_string
=> Secret used as seed for the OTP - base32secret
-
base32_encoded_random_12byte_string
=> Alternative way to set secret (base32 encoded) - when
-
epoch
=> Time used for comparison of OTPs - tolerance
-
1
=> Due to time sync issues, you may want to tune this and compare this many OTPs before and after
Utility Functions
generate_otp
=>-
Create a TOTP URI using the parameters specified or the defaults from the new() method above
Usage:
$gen->generate_otp( digits => [6|8], period => [30|60], algorithm => "SHA1", #currently only this supported secret => "some_random_stuff", issuer => "example.com", user => "some_identifier", ); Google Authenticator displays <issuer> (<user>) for a TOTP generated like this
validate_otp
=>-
Compare a user-supplied TOTP using the parameters specified. Obviously the secret MUST be the same secret you used in generate_otp() above/ Returns 1 on success, undef if OTP doesn't match
Usage:
$gen->validate_otp( digits => [6|8], period => [30|60], algorithm => "SHA1", #currently only this supported secret => "the_same_random_stuff_you_used_to_generate_the_TOTP", when => <epoch_to_use_as_reference>, tolerance => <try this many iterations before/after when> otp => <OTP to compare to> );
Revision History
0.0.2
Added Digest::HMAC_SHA1 and MIME::Base32 to cpanfiles requires (still
getting acquainted with L<Minilla>)
0.0.1
Initial Release
DEPENDENCIES
one of MIME::Base32::XS or MIME::Base32
Imager::QRCode if you want to generate QRCodes as well
SEE ALSO
Auth::GoogleAuth for a module that does mostly the same thing
https://tools.ietf.org/html/rfc6238 for more info on TOTPs
CAVEATS
Only SHA1 currently supported. It should be trivial to add SHA256 and SHA512, but I didn't bother
Some stuff definitely isn't as efficient as it can be
BUGS
Initial release...what do you expect ;)
ACKNOWLEDGEMENTS
Github user j256 for his example implementation
Gryphon Shafer <gryphon@cpan.org> for his Auth::GoogleAuth module that does mostly the same job, but I discovered after I had written most of this
AUTHOR
Thanos Chatziathanassiou <tchatzi@arx.net> http://www.arx.net
COPYRIGHT
Copyright (c) 2020 arx.net - Thanos Chatziathanassiou . All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.