In examining our database storage of hashed passwords with salts, I note a high rate of salt collisions, i.e., there are far too many cases where two table rows have the same salt stored.
One remediation is to immediately begin generating "better" salts as we store new salted-and-hashed passwords.
We run PHP 5.3 in production. That means we probably can't use libraries which say they require PHP 5.4+. (I say "probably" because our CentOS integration does include some PHP 5.4 features. We're investigating compatibility of various libraries.)
We do not have libsodium available at this time.
We do have both the mcrypt and openssl PHP extensions installed and enabled.
I have read through all of Scott's blog posts at Paragonie. The most relevant is How to safely generate random strings and integers in PHP.
I believe my best option for creating a password salt in these circumstances is to use mcrypt for obtaining bytes from /dev/urandom:
$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)
assuming 16 bytes is appropriate for the salt. The PHP documentation does not even say if that first parameter is in bytes! But it does appear to be so.
We have a few tens of millions of users, so allowing for 100 million salts should be reasonable.
Given my constraints, can anyone suggest a better approach than taking 16 random bytes from /dev/urandom via mcrypt extension?
To be sure, we are also working on other upgrades to get us to better library availability, stronger hashing, etc. That's outside the scope of this question.
PBKDF2
will give you higher security. This library tells you why.