Jugando un rato con la aplicación de Google Authenticator (disponible para Android e iOS), hice un pequeño programa en Perl que te permite utilizar la mencionada app.
Este programa utiliza un algoritmo conocido como TOPT (Time-based One-Time Password)
Usa las siguientes librerías:
- Auth::GoogleAuth que consolida varias funciones comunes para que lo manejes como objetos
- Convert::Base32 para la conversión de tu clave secreta a un hash base 32
- Imager::QRCode para generar un jpg con el código QR para que suscribas tu programa a la aplicación de Google Authenticator. Es importante que tengas instaladas la librerias de jpeg, o bien, instalar imager desde tu manejador de paquetes (apt-get, yum, etc.) o CPAN
si invocas el programa sin parámetros te dará está información:
Usage: 1) for Gogle authenticator verification: ./two_factor.pl [Code] 2) To generate qr code for suscribe on Google Authenticator app: ./two_factor.pl -qr The file is named 'two_factor.jpg' 3) print all info (passphrase, base32, issuer and key_id): ./two_factor.pl -info 4) print One Time Password like the Google Authenticator app: ./two_factor.pl -code
y el código del programa “two_factor.pl” a continuación…
#!/usr/bin/perl use strict; use Auth::GoogleAuth; use Convert::Base32; use Imager::QRCode; if ($ARGV[0] ne '') { my $auth = Auth::GoogleAuth->new({ secret => 'A long passphrase to avoid easy hacker attack', issuer => 'Your name/Company', key_id => 'your@mail.com', }); $auth->secret32( encode_base32( $auth->secret() ) ); if ($ARGV[0] eq '-qr') { my $qrcode = Imager::QRCode->new( size => 4, margin => 1, version => 1, level => 'M', casesensitive => 1, lightcolor => Imager::Color->new(255, 255, 255), darkcolor => Imager::Color->new(0, 0, 0), ); my $leyend = 'otpauth://totp/'. $auth->issuer() . ':' . $auth->key_id() . '?secret=' . $auth->secret32() .'&issuer=' . $auth->issuer(); $leyend =~ s/\s/\%20/g; my $img = $qrcode->plot("$leyend"); $img->write(file => "two_factor.jpg"); } elsif ($ARGV[0] eq '-info') { print 'Passphrase: ' . $auth->secret() . "\n"; print ' base 32: ' . $auth->secret32() . "\n"; print ' Issuer: ' . $auth->issuer() . "\n"; print ' Key_id: ' . $auth->key_id() . "\n"; } elsif ($ARGV[0] eq '-code') { print 'OTP: ' . $auth->code() . "\n"; } else { if ($auth->verify("$ARGV[0]")) { print "Valid\n"; } else { print "Invalid\n"; } } $auth->clear(); } else { print "Usage:\n\n"; print " 1) for Gogle authenticator verification:\n\n"; print " ./two_factor.pl \[Code\]\n\n"; print " 2) To generate qr code for suscribe on Google Authenticator app:\n\n"; print " ./two_factor.pl -qr\n\n"; print " The file is named 'two_factor.jpg'\n\n"; print " 3) print all info (passphrase, base32, issuer and key_id):\n\n"; print " ./two_factor.pl -info\n\n"; print " 4) print One Time Password like the Google Authenticator app:\n\n"; print " ./two_factor.pl -code\n\n"; } |
Teniendo el hash en base 32 del passphrase se puede hacer un programa muy corto que solo verifique el código generado por el Google Authenticator.
Ejemplo del programa 2fa.pl:
#!/usr/bin/perl use strict; use Auth::GoogleAuth; my $auth = Auth::GoogleAuth->new({ secret32 => 'ieqgy33om4qhayltonygq4tbonssa5dpebqxm33jmqqgkyltpeqgqyldnnsxeidbor2gcy3l', }); if ($ARGV[0] ne '') { if ($auth->verify("$ARGV[0]")) { print "Valid\n"; } else { print "Invalid\n"; } } else { print "Usage:\n\n"; print " for Gogle authenticator verification:\n\n"; print " ./2fa.pl \[Code\]\n\n"; } $auth->clear(); |