Can I rely on openssl_random_pseudo_bytes() being very random in PHP?

open_ssl_random_pseudo_bytes is a cryptographically secure pseudo random number generator (CSPRNG).

In layman's terms, this means that it can generate an unpredictable, uniformly distributed sequence, that is suitable for key generation. The unpredictable property is important, because even if the full state of the random number generator is known, an attacker cannot recreate previously generated sequences, and it is unfeasible for an external observer to guess the state in order to predict future sequences.

This is in contrast to say a random number generator that takes its seed from the number of seconds past midnight and then generates predictable sequences based on this seed. In this case an attacker can simply set their own system to generate numbers using the same seed and can effectively guess token values in order to use them for their own nefarious purposes.

64 bytes will give you 512 bits of entropy. Since MD5 outputs hashes of 128 bits, there is no advantage of having the entropy generated being greater than 128. If the code is ran one billion times then there is a statistically probable chance of it always being unique because you have an output keyspace of 2128 (3.4 * 1038). The collision rate of MD5 is about 264 which is about 18 billion billion.


You should be aware of PHP bug #70014 which was pretty recent and affects the reliability of openssl_random_pseudo_bytes().

I've been working on paragonie/random_compat, which backports random_bytes() from PHP 7 into PHP 5. One of the fallbacks it supports is openssl_random_pseudo_bytes(), but if it can read directly from /dev/urandom it will prefer that instead.


It's better to use random_bytes than openssl_random_pseudo_bytes.

From the manual(available since php 7.x) :

random_bytes — Generates cryptographically secure pseudo-random bytes

Sample code (from the manual too):

 <?php

   $bytes = random_bytes(5);
   var_dump(bin2hex($bytes));

 ?>