In a PHP application I create a session ID by reading a number of bytes from dev/urandom and then convert each byte to hex with bin2hex(). I woud like to know if this approach is okay, or does the conversion to hex weaken the SID because the number of possible combinations is reduced? Is there a better approach?
bin2hex()
will only be dangerous if you have an imposed character limit. If you read 20 bytes of entropy to fill 20 characters of hex, you might as well have pulled 10 bytes from the OS.
But if you're fine going from 20 bytes of raw binary to 40 hex characters, no security loss occurs.
Is your question actually “How can I generate a string of random hex digits?” If so, here’s your answer (requires PHP 5.3 or later):
function getRandomHex($num_bytes=4) {
return bin2hex(openssl_random_pseudo_bytes($num_bytes));
}
Note that if $num_bytes > 7, the value cannot be represented as an number in PHP without losing precision. A five-byte value (10 hex digits) has about a one-in-a-million chance of collision.