I've always been told that I should use openssl_random_pseudo_bytes
when giving passwords a salt.
But what I would really love to know, is what makes it cryptographically secure. What is the internal difference between rand
, mt_rand
and openssl_random_pseudo_bytes
?
Thanks in advance.
The differences are in short:
rand
uses the libc random number generator (source), which depends on the system and is usually not cryptographically secure mt_rand
uses a known algorithm, the Mersenne Twister, hence the name; this is a fast algorithm that produces well distributed but not cryptographically-secure randomsopenssl_random_pseudo_bytes
directly calls the OpenSSL system for cryptographically-secure randoms (but see the warning in the full description)The properties are also listed in the table below:
rand
For rand
it is stated in mt_rand
:
Many random number generators of older libcs have dubious or unknown characteristics and are slow.
So for rand
you'll have to take a look at your libc to figure out which random is actually used. It's stated on the Mersenne Twister site that it should have comparable speed nowadays, but it's characteristics depends on the system. It doesn't state how it is seeded either, meaning that you could use it for a game or such, but not for much else.
mt_rand
The Mersenne Twister is a well known algorithm that produces rather well distributed random numbers. It has a very long period, which means that it takes a long time before a previous state is encountered (if this happens it stays in loop, the size of the loop is called the period). MT is not secure because it is possible to reconstruct its secure state given enough data. This means that if you first generate a key, and then use the algorithm for something else, then an attacker may recreate the key given enough output. Furthermore, a non-secure seed as the system time is used upon creation.
openssl_random_pseudo_bytes
OpenSSL's random number generator is usually cryptographically secure (see note below); this means that it is not possible to re-calculate the internal state given the output of the generator.
OpenSSL's pseudo random number generator is constructed using a hash function, currently MD5, which should still be secure for generating random numbers. It is well distributed and - like the MT algorithm - has a high period. OpenSSL's rand
is much slower than MT, but it should still get a rather good speed.
It has the advantage over OS random number generators that it does not need additional threads or system calls. OpenSSL uses the operating system random number generator (+ possible other sources) to create the initial seed. The OS random generators are normally the best possible random number generators available, as the OS has access to sources of entropy not directly available to libraries and applications.
Warning: on the Wiki of OpenSSL it is stated that:
RAND_pseudo_bytes
returns pseudo-random bytes which can be cryptographically strong. The function returns1
if the bytes are cryptographically strong, and0
otherwise. If your application has high integrity requirements, it should not useRAND_pseudo_bytes
.
Which is reflected by the PHP function:
If passed into the function, this will hold a boolean value that determines if the algorithm used was "cryptographically strong", e.g., safe for usage with GPG, passwords, etc.
TRUE
if it did, otherwiseFALSE
This means it may still be insecure for e.g. long term keys.
Warning #2: additional insight shows that the PRNG of OpenSSL may not always be secure regardless of the return value. So additional care should be taken before choosing OpenSSL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With