Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Authen-OATH CPAN distribution.

Report information
The Basics
Id: 67777
Status: resolved
Priority: 0/
Queue: Authen-OATH

People
Owner: Nobody in particular
Requestors: tlyons [...] ivenue.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: v1.0.0
Fixed in: v1.0.0



Subject: Will not verify with Google Authenticator
I have built Authen::OATH under perl-5.10.1 (perlbrew). I am attempting to verify TOTP using Google Authenticator, but the hashes are not matching. I tried a tight loop that checked 100K timeblocks (30 second chunks) above and 100K timeblocks below the current time, no hashes matched in either case. My clocks are sync'd using ntp so I'm positive the accuracy is within a few hundreths of a second. The attached script uses the Auth Info represented by the test QRCode generated here: https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/todd@tlyons%3Fsecret%3DIWYIR3ES2MMGNSIO The above belongs to a box that is just a test account, it is not used for actual authentication. Am I doing something wrong? Does the Google Authenticator use some enhancement of the spec that Authen::OATH does not support? Linux tlyons 2.6.35-28-generic #49-Ubuntu SMP Tue Mar 1 14:40:58 UTC 2011 i686 GNU/Linux [todd@tlyons ~/projects/google-authenticator/perl]$ perl check_auth.pl 413196 Passed token 413196 Calculated TOTP 735136 Right now I'm comparing what the OATH.pm does compared to the google-authenticator pam module, but do not see anything that indicates to me what I am doing wrong.
Subject: check_auth.pl
#!/usr/bin/perl use strict; use warnings; use Authen::OATH; my $token = shift() || usage(); sub usage { my $prog = `basename $0`; chomp $prog; print <<EOF; Usage: $prog token EOF exit 0; } # This will be a database lookup to obtain the key once past testing my $key = 'IWYIR3ES2MMGNSIO'; #my $oath = Authen::OATH->new( digest => "Digest::HMAC_SHA1" ); my $oath = Authen::OATH->new( ); my $totp = $oath->totp( $key ); print <<EOF; Passed token $token Calculated TOTP $totp EOF
Subject: Invalid problem report
From: tlyons [...] ivenue.com
On Tue Apr 26 17:27:52 2011, mrballcb wrote: Show quoted text
> I am attempting to verify TOTP using Google Authenticator > The attached script uses the Auth Info represented by the test QRCode > generated here: >
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/todd@tlyons%3Fsecret%3DIWYIR3ES2MMGNSIO Show quoted text
> The above belongs to a box that is just a test account, it is not used > for actual authentication. > > Am I doing something wrong?
*YES* <sigh> I was passing the base32 encoded secret to totp() when I should have been passing the raw secret. Exact code: my $key = 'IWYIR3ES2MMGNSIO'; my $oath = Authen::OATH->new(); my $totp = $oath->totp($key); It works properly if you change the last line to: my $secret = decode_base32($key); my $totp = $oath->totp($secret); Resulting output: [todd@tlyons ~]$ perl test.pl 605855 Key : IWYIR3ES2MMGNSIO Secret : E�����f Secret (decimal): 69 176 136 236 146 211 24 102 201 14 Authen::OATH : 605855 Raw perl : 605855 Compared to Google Auth phone app: 605855 The "Raw perl" line is a function which does the totp verification. I found it in a test cgi for a Google Authenticator apache module. Please do consider that this case is closed, call it a rejected bug as well (PEBKAC). At most, consider adding a comment somewhere in the perldoc that the secret key is not the base32 encoded version, it must be the raw bytes. But if that requirement is obvious to people who work with this on a regular basis, it's a clarification that doesn't need to be made.
On Tue Aug 09 16:52:03 2011, mrballcb wrote: Show quoted text
> On Tue Apr 26 17:27:52 2011, mrballcb wrote:
> > I am attempting to verify TOTP using Google Authenticator > > The attached script uses the Auth Info represented by the test QRCode > > generated here: > >
> https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/todd@tlyons%3Fsecret%3DIWYIR3ES2MMGNSIO
> > The above belongs to a box that is just a test account, it is not > > used > > for actual authentication. > > > > Am I doing something wrong?
> > *YES* <sigh> > > I was passing the base32 encoded secret to totp() when I should have > been passing the raw secret. Exact code: > > my $key = 'IWYIR3ES2MMGNSIO'; > my $oath = Authen::OATH->new(); > my $totp = $oath->totp($key); > > It works properly if you change the last line to: > my $secret = decode_base32($key); > my $totp = $oath->totp($secret); > > Resulting output: > [todd@tlyons ~]$ perl test.pl 605855 > Key : IWYIR3ES2MMGNSIO > Secret : E�����f > Secret (decimal): 69 176 136 236 146 211 24 102 201 14 > Authen::OATH : 605855 > Raw perl : 605855 > Compared to Google Auth phone app: 605855 > > The "Raw perl" line is a function which does the totp verification. I > found it in a test cgi for a Google Authenticator apache module. > > Please do consider that this case is closed, call it a rejected bug as > well (PEBKAC). At most, consider adding a comment somewhere in the > perldoc that the secret key is not the base32 encoded version, it must > be the raw bytes. But if that requirement is obvious to people who > work > with this on a regular basis, it's a clarification that doesn't need > to > be made.
Thanks for this! I've added a note in the docs about this use case. Best, Olaf