should i use urandom or openssl_random_pseudo_byte

2020-07-06 07:39发布

问题:

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);

回答1:

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:

$salt = openssl_random_pseudo_bytes(40, $cstrong);
if (! $cstrong) {
    exit('This should not happen');
}


回答2:

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 in man unrandom:

"A read from the /dev/urandom device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver. Knowledge of how to do this is not available in the current unclassified literature, but it is theoretically possible that such an attack may exist. If this is a concern in your application, use /dev/random instead."

However, the same is actually true of openssl_random_pseudo_bytes (which calls the OpenSSL function RAND_pseudo_bytes internally), as noted in the OpenSSL documentation:

"RAND_pseudo_bytes() puts num pseudo-random bytes into buf. Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be unique if they are of sufficient length, but are not necessarily unpredictable. They can be used for non-cryptographic purposes and for certain purposes in cryptographic protocols, but usually not for key generation etc."

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.



标签: php random salt