Using Bycrypt in Perl
bcrypt, blowfish, hash, perl, salt
Solution
If you're already using `Authen::Passphrase`, you can let it do all the work for you:
use Authen::Passphrase::BlowfishCrypt;
my $password = "Sneaky!";
my $ppr = Authen::Passphrase::BlowfishCrypt->new(
cost => 8,
salt_random => 1,
passphrase => $password,
);
my $string = $ppr->as_rfc2307;
print $string, "\n";
# Then, to verify the password
$ppr = Authen::Passphrase->from_rfc2307($string);
if ($ppr->match($password)) {
print "OK\n";
}
If you want to work with `Crypt::Eksblowfish::Bcrypt` directly, note that it expects a 16-byte string as salt:
use Crypt::Eksblowfish::Bcrypt qw(bcrypt bcrypt_hash en_base64);
my $password = "Sneaky!";
my $salt = '';
for my $i (0..15) {
$salt .= chr(rand(256));
}
my $hash = bcrypt_hash({
key_nul => 1,
cost => 8,
salt => $salt,
}, $password);
# or
my $salt_base64 = en_base64($salt);
my $string = bcrypt($password, "\$2a\$08\$$salt_base64");
print $string, "\n";
Problem
``` #!/usr/bin/perlml -Tw use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); # show errors in browser use Authen::Passphrase::BlowfishCrypt; use Bytes::Random::Secure; print "Content-type:text/html\n\n"; # read the CGI params my $cgi = CGI->new; my $username = $cgi->param("username"); my $password = $cgi->param("password"); if ($username =~ /[^a-zA-Z0-9]/) { die "Illegal characters" }; if ($password =~ /[^a-zA-Z0-9]/) { die "Illegal characters" }; my $settings = './settings.cnf'; use DBI; my $dsn = "DBI:mysql:DB;" . "mysql_read_default_file=$dbsettings"; my $dbh = DBI->connect($dsn, undef, undef,{RaiseError=>1}) or die "Could not connect to database: $DBI::errstr"; # check the username and password in the database my $statement = qq{SELECT username,password FROM table WHERE username=? and password=?}; my $sth = $dbh->prepare($statement) or die $dbh->errstr; $sth->execute($username, $password) or die $sth->errstr; my ($userID) = $sth->fetchrow_array; # create a JSON string according to the database result my $json = ($userID) ? qq{{"success" : "login is successful", "userid" : "$userID"}} : qq{{"error" : "username or password is wrong"}}; # return JSON string print $json; $dbh->disconnect(); ``` I'm now trying to implement bcrypt, over here... but unable to find any good example to learn from. I am having trouble generating random salts, since the documentation on cpan is so obscure for a perl nobie like me. I tried something like this: ``` my $gen = Authen::Passphrase::SaltedSHA512->new( passphrase => 'Sneaky!' ); my $salt = $gen->salt_hex; my $hash = bcrypt_hash({ key_nul => 1, cost => 8, salt => $salt, }, $password); ``` tried to print $hash, got a "salt must be 16 octet long exactly" error That's just me being lazy, and ignorant.. firing a arrow in the darkness. I really need a nice example, my head hurts, after 5 hours of stray thoughts and googling. Would really appreciate the help. PS: I have seen 2-3 very vague examples, one here in stackflow, those didn't give me any leads. Something fresh is desired.