ETOOBUSY 🚀 minimal blogging for the impatient
Random bytes and co.
TL;DR
Generating some randomness for seeds.
In previous post Bcrypt password hashing we took a look at the Crypt::Eksblowfish::Bcrypt module and eventually came out with the following function:
sub create_account ($username, $password, $cost, $salt = undef) {
$salt //= pack 'C*', map {int rand 256} 1 .. 16;
my $settings = sprintf '$2a$%02d$%s', $cost, en_base64($salt);
save_user($username, bcrypt($password, $settings));
}
The $salt
parameter is aimed at avoiding a lot of pre-computation of
stuff etc. to strengthen the security of the whole system, and we are
filling in a default one leveraging Perl’s internal rand
function.
As the documentation makes clear:
rand is not cryptographically secure. You should not rely on it in security-sensitive situations. As of this writing, a number of third-party CPAN modules offer random number generators intended by their authors to be cryptographically secure, including: Data::Entropy, Crypt::Random, Math::Random::Secure, and Math::TrulyRandom.
I think it’s probably fair to add that there are other modules too, like Crypt::Random::Seed and Bytes::Random::Secure::Tiny.
In my typical situation, though, I’m in a Linux environment not
from ages ago, so we might rely on /dev/urandom
directly:
sub salt_please {
open my $fh, '< :raw :bytes', '/dev/urandom'
or die "open('/dev/urandom'): $!\n";
my $retval = '';
while ((my $len = length $retval) < 16) {
read($fh, $retval, 16 - $len, $len) // die "read(): $!\n"
}
close $fh;
return $retval;
}
This is probably an overkill implementation of read 16 bytes from
/dev/urandom
- in particular, I don’t expect the while
loop to
really kick in more than once.
So now you can put some salt on your seeds, uh?