I am developing a site in php 5.4 and i was wondering which is better to use to gen a random salt for password security?
$salt = sha1(openssl_random_pseudo_bytes(23));
or
$seed = '';
$a = @fopen('/dev/urandom','rb');
$seed .= @fread($a,23);
$salt = sha1(seed);
or should i just go with:
$salt = openssl_random_pseudo_bytes(40);
or
$salt = '';
$a = @fopen('/dev/urandom','rb');
$salt .= @fread($a,23);
In practice, there is almost certainly no difference.
Both
openssl_random_pseudo_bytes
and/dev/urandom
provide a cryptographically secure source of pseudorandom bytes. Neither is guaranteed to be truly random, but in practice, both are expected to be indistinguishable from true randomness by any known or foreseeable techniques.Kmkaplan is technically correct in noting that
/dev/urandom
could return theoretically predictable output under certain conditions, as noted inman unrandom
:However, the same is actually true of
openssl_random_pseudo_bytes
(which calls the OpenSSL functionRAND_pseudo_bytes
internally), as noted in the OpenSSL documentation:Neither of these warnings should actually scare you from using these methods — the weaknesses they describe are only theoretical, except possibly under certain contrived circumstances (such as on a diskless embedded device with no hardware RNG immediately after boot-up), and should not be of practical concern in situations where PHP is normally deployed.
The upshot is, neither of these random number generation methods is going to be the weakest link in your cryptosystem, so you can safely choose either one. If you're feeling paranoid, you could even use both.
Ps. One advantage of
openssl_random_pseudo_bytes
is that it works on Windows, too. On the other hand,/dev/urandom
is available on Unix even if the OpenSSL PHP extension is not installed. Thus, for maximum portability, you should indeed implement support for both.Also, always check that you indeed received as many bytes as you expected; for example, the
/dev/urandom
based code in your question above could silently return an empty string on systems like Windows where/dev/urandom
does not exist.For security purposes you are better off using
openssl_random_pseudo_bytes
. OpenSSL takes care of gathering enough entropy to serve you good randomness./dev/urandom
is devised to never block and could be tricked into giving you not so random bytes.With random bytes you do not need to run them through SHA1.
To sum it all, do: