I'm looking to generate a UUID (version 4) in PHP however all the methods I've seen use mt_rand()
which I want to avoid as it poses security implications if the UUID generated can be guessed.
I have come up with the following:
function uuid_v4()
{
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
random_mcrypt(), random_mcrypt(),
// 16 bits for "time_mid"
random_mcrypt(),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
random_mcrypt(0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
random_mcrypt(0x3fff) | 0x8000,
// 48 bits for "node"
random_mcrypt(), random_mcrypt(), random_mcrypt()
);
}
function random_mcrypt($max = 0xffff)
{
$int = current(unpack('S', mcrypt_create_iv(2, MCRYPT_DEV_URANDOM)));
$factor = $max / 0xffff;
return round($int * $factor);
}
Is this sufficient for my needs? Is there anything I should be aware of?
EDIT: This has been marked as duplicate, it isn't cuz in my question I say that other answers (including the one that his was marked a duplicate of) use mt_rand() which I didn't want to use for security reasons.
EDIT 2: To be clear, this is not a question on how to you generate a v4 UUID but does my method improve on the security of an implementation of methods using mt_rand()
and are there any pitfalls I should know about.
Whether it is sufficient for your needs depends on your threat model. Do you have a bunch of kids who want to mess with you, corporate espionage fears, or is the entire Chineese government trying to break your system?
MCRYPT_DEV_URANDOM
generates entropy from /dev/urandom. This avoids DOS attacks on /dev/random where you ask for a bunch of UUIDs and deplete the system entropy until the program blocks. However, it also means you have absolutely no guarantee as to how many bits of entropy are actually in your UUID - none whatsoever.
There have been threat models written which start with the assumption that you ping a server with thoudsands of requests to deplete the entropy of /dev/urandom and then start cracking the urandom key.
If you truly care about security, there are cryptographic PRNGs which are designed to be secure, like Blum Blum Shub.