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?


Comments? Octodon, , GitHub, Reddit, or drop me a line!