# Very simple proof of concept for storing bcrypted salted passwords.
# if the file 'passwd' does not exist, we will accept a password on stdin
# and store it in said file.

# If the file does exist, we will read it and prompt for a password, and check
# if it matches what we stored.

use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash);

sub salt {
my $length = shift;
my @octets = map { int(rand(256)) } (1..$length);
return pack('C' x $length, @octets);
}

sub myCrypt {
my ($password, $salt) = @_;
my %settings = (
key_nul => 1,
cost => 8,
salt => $salt,
);
return bcrypt_hash(\%settings, $password);
}

$| = 1;
print "Enter password: ";
my $entered = <>;
chomp $entered;

if (-e 'passwd') {
open(my $fh, '<', 'passwd');
my ($stored, $salt) = <$fh>;
chomp $stored;
chomp $salt;
close $fh;

my $crypted = myCrypt($entered, $salt);
print $crypted eq $stored ? 'Correct' : 'Incorrect';
print "\n";
}
else {
my $salt = salt(16);
open(my $fh, '>', 'passwd');
my $crypted = myCrypt($entered, $salt);
print $fh "$crypted\n$salt\n";
close $fh;
print "Saved.\n";
}