$ perl bcrypt_2a
Plain password is bcrypt as $2a$10$q4VIJI0lTJBh4O6Kfo/f/uwvN4CQWPbFutc8hO8bKmn3Rz6qV4xcS
Valid Password password
####
$ perl bcrypt_2y
bad bcrypt settings at bcrypt_2y line 22
####
#!/usr/bin/perl
# File: bcrypt_2a
use Crypt::Eksblowfish::Bcrypt;
use Crypt::Random;
$password = 'password';
$encrypted = encrypt_password($password);
print "Plain $password is bcrypt as $encrypted\n";
if (check_password($password, $encrypted)) {
print "Valid Password $password\n"
}
sub encrypt_password {
my $password = shift;
my $salt = shift || salt();
my $settings = '$2a$10$'.$salt;
return Crypt::Eksblowfish::Bcrypt::bcrypt($password, $settings);
}
sub check_password {
my ($plain_password, $hashed_password) = @_;
# Regex to extract the salt
if ($hashed_password =~ m!^\$2a\$10\$([A-Za-z0-9+\\\.\/]{22})!) {
# Use a letter by letter match rather than a complete string match to avoid timing attacks
my $match = encrypt_password($plain_password, $1);
my $bad = 0;
for (my $n=0; $n < length $match; $n++) {
$bad++ if substr($match, $n, 1) ne substr($hashed_password, $n, 1);
}
return $bad == 0;
}
else {
return 0;
}
}
# Return a random salt
sub salt {
return Crypt::Eksblowfish::Bcrypt::en_base64(Crypt::Random::makerandom_octet(Length=>16));
}
####
#!/usr/bin/perl
# File: bcrypt_2y
use Crypt::Eksblowfish::Bcrypt;
use Crypt::Random;
$password = 'password';
$encrypted = encrypt_password($password);
# from another program, a bcrypt 2y of 'password' = '$2y$10$iG2fZoSKzWUVn65cMDGL0uG8sWvy0G0G2Z/1Fll7zcBvEIOvn8qLG';
print "Plain $password is bcrypt as $encrypted\n";
if (check_password($password, $encrypted)) {
print "Valid Password $password\n"
}
sub encrypt_password {
my $password = shift;
my $salt = shift || salt();
my $settings = '$2y$10$'.$salt;
return Crypt::Eksblowfish::Bcrypt::bcrypt($password, $settings);
}
sub check_password {
my ($plain_password, $hashed_password) = @_;
# Regex to extract the salt
if ($hashed_password =~ m!^\$2y\$10\$([A-Za-z0-9+\\\.\/]{22})!) {
# Use a letter by letter match rather than a complete string match to avoid timing attacks
my $match = encrypt_password($plain_password, $1);
my $bad = 0;
for (my $n=0; $n < length $match; $n++) {
$bad++ if substr($match, $n, 1) ne substr($hashed_password, $n, 1);
}
return $bad == 0;
}
else {
return 0;
}
}
# Return a random salt
sub salt {
return Crypt::Eksblowfish::Bcrypt::en_base64(Crypt::Random::makerandom_octet(Length=>16));
}