How do you create "good" random md5 hashes in php?
Asked Answered
I

2

0

For several cases I would need to create random md5 hashes. Do you know what the best / most secure ways of doing this are?

Some use cases

  • Verifying an email address
  • Resetting passwords
  • Some kind of session id used for authentication, instead of password (eg: when someone hits "remember me", I would not like to store the pass in a cookie)

Background

I know that rand() should not be used for security relevant applications. For that reason I went with:

md5( uniqid(mt_rand(),true) );

Now I read in the php manual about uniqid(), that it must not be used for security purposes. Which kind of makes sense because it usually just gives something like a timestamp.

But is it fine when combined with a random prefix - mt_rand() - like I do, or is there something better that should be used in this case?

Thx in advance!

Infliction answered 4/6, 2014 at 12:27 Comment(4)
See this, if it helps.Isochor
You can use base64_encode php.net/manual/en/function.base64-encode.php to encode.Triplet
@Log1cツ: Thx, there is a lot in there! Most of all probably the function openssl_random_pseudo_bytes() as alternative.Infliction
@Prava-MindfireSolutions: The encoding is not so much the problem, as is the data for it (also base64 could easily be decoded/"reversed").Infliction
H
4

You don't need "MD5 hashes", you simply need a random string of characters. These need not have anything to do with MD5 at all. So all you need is a good PRNG. For instance:

$token = mcrypt_create_iv($rawLength, MCRYPT_DEV_URANDOM);
// or
$token = openssl_random_pseudo_bytes($rawLength);
// or
$token = file_get_contents('/dev/urandom', false, null, 0, $rawLength);

Then base64_encode or bin2hex the raw value to get an ASCII character string.

Hydroxylamine answered 4/6, 2014 at 12:34 Comment(7)
That is actually a pretty good answer!! Just the problem in my case, that my server runs on a windows machine, so no /dev/urandom there :-/Infliction
Well, there are enough alternatives... :) Actually, have a look at this library, which has many fallbacks: github.com/ircmaxell/password_compat/blob/master/lib/…Hydroxylamine
That looks pretty good, will give it a more thorough look. Just out of interest, what do you think of my original code with mt_rand() in combination with uniqid()? The combination of exact microsecond plus a "kind of" random algorithm seems not too bad to me, or am I missing something?Infliction
It's probably going to be okay in practice. However, IMO it's approaching it from the wrong side. You're generating a value with some entropy from an okay-but-not-great PRNG and feed that as seed into another okay-but-not-so-great PRNG which then gets hashed with a not-really-great hash, all of which just serves to gradually decrease the entropy, if anything. You should just use a high-entropy source to begin with and be done with it.Hydroxylamine
Well that sounds like a really good answer! Thx!! Especially "... which then gets hashed with a not-really-great hash" ^^ ... but true!Infliction
One more thing, in that context, since all those functions deliver random BYTES, do you think it would be "safe" to use md5/sha to wrap it, since it has to be in the url and just urlencode() makes it rather inconvenient to compare to the dbs. Or would you do/store it differently? Thx again! Eg.: md5(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM));Infliction
Again, just bin2hex or base64_encode those bytes. The bytes are already random, you simply want to present them in a different base. You essentially get them as raw base 256, and you want to represent them in base 16 (hex) or base 64 to make them readable/transportable.Hydroxylamine
T
0

I just finished devloping a fairly robust Bash script that generates decent quality md5sum's. You can find it https://code.google.com/p/gen-uniq-id/source/browse/gen_uniq_id.bsh

It has the following features:

A time stamp down to nanoseconds,

A user-modifiable amount of collected data from /dev/urandom (default is .25 seconds),

A user-modifiable amount of collected mouse-movement data (default is .25 seconds, just use xinput --list and run it once with -M<your_mouse_device_id>),

A dynamically modifiable text statement that may be set as a default or sent in dynamically with each call e.g. -s"$(history | tail -5)".

You can probably easily port over to PHP or just call it from PHP via shell_exec:
$random_md5sum = shell_exec('/path/to/gen_uniq_id.bsh -m1 -r1 -s"favorite quote$(history | tail -5)"');

Turgid answered 10/3, 2015 at 22:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.