# NAME

Authen::TOTP - Interface to RFC6238 2FA

Version 0.0.1

# 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.1
          Initial Release

# DEPENDENCIES

[Digest::HMAC\_SHA1](https://metacpan.org/pod/Digest%3A%3AHMAC_SHA1),

one of
[MIME::Base32::XS](https://metacpan.org/pod/MIME%3A%3ABase32%3A%3AXS) or [MIME::Base32](https://metacpan.org/pod/MIME%3A%3ABase32)

[Imager::QRCode](https://metacpan.org/pod/Imager%3A%3AQRCode) if you want to generate QRCodes as well

# SEE ALSO

[Auth::GoogleAuth](https://metacpan.org/pod/Auth%3A%3AGoogleAuth) for a module that does mostly the same thing

[https://tools.ietf.org/html/rfc6238](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 <[email protected]> for his [Auth::GoogleAuth](https://metacpan.org/pod/Auth%3A%3AGoogleAuth) module
that does mostly the same job, but I discovered after I had written
most of this

# AUTHOR

Thanos Chatziathanassiou <[email protected]>
[http://www.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.