Super Gen Pass
I had been wanting a perl implementation of the
Super Gen Pass script. I couldn't find one anywhere, so I wrote the one below. It is pretty simple, but I'm making it available because I had a hard time getting the Perl hash to give the same result as the javascript one used by SGP. I've tested it with a lot of password / domain combinations and have always found it to give the same results. Please let me know if you make any improvements or find any bugs. The script can also be downloaded
here.
#!/usr/bin/perl
# The following was written by John R Saathoff
# www.jrsaathoff.com
# To the extent possible under law, John Saathoff has waived all
# copyright and related or neighboring rights to this work.
use MIME::Base64;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use Getopt::Long;
my ($opt_d, $opt_p, $opt_h, $opt_l) = (0,0,0,10);
$result = GetOptions ("d|domain=s" => \$opt_d, # string
"p|password=s" => \$opt_p, # string
"h|?|help" => \$opt_h, # boolean
"l|length=i" => \$opt_l); # integer
if (! $result) { die "\nIncorrect input, run -h for help\n"; }
if ($opt_h) { usage(); }
# If not provided on the command line prompt for domain and master password
if (! $opt_p) {
print "master password = ";
# Don't display the password on the terminal
# but probably only works in linux
system("stty -echo");
chop($opt_p = <>);
print "\n";
system("stty echo");
}
if (! $opt_d) {
print "domain = ";
chomp($opt_d = <>);
}
# MD5 the starting string until we get a valid password or at least 10 times
$password = "";
$md5string = $opt_p.':'.$opt_d;
$i = 0;
while (($i < 10) || (! validpassword())) {
$md5string = md5_base64($md5string);
# The following three lines are simply to make the Perl MD5
# return the same result as the javascript MD5 funciton
$md5string = $md5string.'AA';
$md5string =~ s/\+/9/g;
$md5string =~ s/\//8/g;
$password = substr($md5string, 0, $opt_l);
$i++;
}
print "site password = $password\n";
########### validpassword ###########################
# Returns true if global variable $password is valid
sub validpassword {
$valid = 1;
# Always contain at least one uppercase letter of the alphabet
# Always contain at least one numeral
# Always start with a lowercase letter of the alphabet
$valid = $valid && ($password =~ m/[A-Z]/);
$valid = $valid && ($password =~ m/[0-9]/);
$valid = $valid && ($password =~ m/^[a-z]/);
return $valid;
}
########### USAGE ###########################
# Print help and exit program
sub usage {
print "\n";
print "-d, --domain the site domain\n";
print "-p, --password your master password\n";
print "-l, --length the length of the generated password (default is 10)\n";
print "-h, -?, --help prints help and exits\n";
die "\n";
}