开发者

Generating a salt in PHP

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)


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() and password_verify().


Note: mcrypt has been deprecated in PHP 7.1. Skip to the up-to-date answer.

You might want to take a look at the documentation (and comments) for mcrypt_create_iv().


Note: mcrypt has been deprecated in PHP 7.1. Skip to the up-to-date answer.

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 constant MCRYPT_DEV_URANDOM is defined.

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);

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.


uniqueid is not well suited for generating a random string as it too is microtime 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,

 uniqid('', 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:

$length = 16;
base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM))
//> hlZuRJypdHFQPtI2oSFrgA==
strlen(base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM)))
//> 16

Reducing the character-alphabet to 2^6Bit increases the size, which is accounted for above.


Read from /dev/urandom, or use openssl_random_pseudo_bytes().


Looks like this question has an accepted answer but I just want to additionally state after a bit of research and reading this thread that you might add some security if you don't put all your eggs in one basket.

I might suggest not relying solely on PHP to create your salts and hashing your passwords. You can obfuscate your solution a little more if you let the database do part of the work.

Someone suggested just using password_hash() and password_verify(). While those are great methods, I strongly recommend sticking to the idea of incorporating a salt in addition to these.

To answer the question, a salt can be anything that is truly random and enforced as unique to the user. You can technically generate it however you wish as long as you adhere to those 2 rules.

a couple of good resources:

https://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right https://auth0.com/blog/adding-salt-to-hashing-a-better-way-to-store-passwords/


uniqid() should be fine for this purpose.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜