What's the best way to generate a cryptographically secure 32 bytes salt in PHP, without depending on libraries seldom included in typical PHP installations?
After some googling I discovered that mt_rand
is not considered secure enough, but I haven't found a suggestion for a replacement. One article suggested reading from /dev/random
but not only this won't work on windows; it is also very slow.
I want a reasonable balance between security and speed (ie, it shouldn't take 20 seconds to generate 512 bytes, like /dev/random
usually does)
You can use the function
mycrypt_create_iv()
, since PHP Version 5.3 it also uses the random source on a Windows server (not only on Unix). Before using it, you should check if the constantMCRYPT_DEV_URANDOM
is defined.Unlike random, urandom does not block the server, if there is not enough entropy available. Since the password salt should be unique (not necessarily random), urandom seems to be a good choice to me.
Read from
/dev/urandom
, or useopenssl_random_pseudo_bytes()
.uniqueid
is not well suited for generating a random string as it too ismicrotime
based. A CPU Cycle is generally much shorter than a microtime-tick, which may lead to possible constancy for a given variable within loops. Setting the second parameter "entropy" to true,will provide increased randomness.
To get a random string that is well compatible with most character-sets,one may apply base64 encoding to the mcrypt initilization vector function
mcrypt_create_iv
:Reducing the character-alphabet to 2^6Bit increases the size, which is accounted for above.
This is easier in PHP 7: Just use
$salt = random_bytes($numberOfDesiredBytes);
to generate a salt.What do you need a salt for, anyway? If it's for passwords, just use
password_hash()
andpassword_verify()
.I think
microtime()
is enough.Strangely, but I am still getting downvotes for this answer.
Though the only explanation I get is that microtime is predictable.
It sounds strange to me as salt always assumed as openly known - so, there is no use for prediction at all.
You might want to take a look at the documentation (and comments) for
mcrypt_create_iv()
.