Random data generator
Random isn't always random enough. The built in random functions in PHP may be good enough for displaying a random quote, or a random image. But when it comes to generating random data for use in encryption keys or other security related things the pseudo random generator provided by phpSec is preferable.
phpSec provides you with a number of different methods of collecting random data. All of them uses the same pseudo random generator, the only difference is how they return the data. All the methods are called statically from the phpsecRand class.
Random numbers
Getting random numbers with phpSec is done with the phpsecRand::int() method. This method takes two arguments. The first is the lowest possible number, and the second is the highest possible number. The following example will produce a random number between 1 and 10.
echo phpsecRand::int(1, 10);
Random strings
Random strings can be used for example to create new passwords to users in case they have lost the current password.
Random strings are created with the phpsecRand::str() method. This method takes only one argument, the length of the string to be generated. The following example will produce a random string of 10 characters.
echo phpsecRand::str(10);
It is also possible to define what characters to use when generating the string.
phpsecRand::$_charset = 'abcdef'; echo phpsecRand::str(10);
Random array keys
phpSec can also select random keys from an array. This is done with the phpsecRand::arrayRand() This method takes two arguments, the first one is the array to pick random keys from, and the second is the number of keys to pick. If only one key is picked this method returns a string. If multiple keys are picked it will return an array.
phpsecRand::$_charset = 'abcdef'; $array = array( 'key' => 'foo', 'bar' ); print_r(phpsecRand::arrayRand($array, 1));
Random data
It is also possible to collect random bytes from phpSec. This can be used if you don't need data that is printable. A good example is if you need an encryption key. Binary data is collected using phpsecRand::bytes(). This method only takes one argument, how many bytes to produce.
echo phpsecRand::bytes(32);
Under the hood
So, what makes the randomness generated by phpSec more random than the regular randomness provided by PHP?
If you take a look at phpsecRand::bytes(), I can explain. This is the method that generates the randomness for all of the phpsecRand methods. This method is inspired from a blogpost by Enrico Zimuel.
/**
* Generate random data.
*
* @param integer $len
* @return binary
*/
public static function bytes($len) {
$strong = false;
if(function_exists('openssl_random_pseudo_bytes')) {
$rnd = openssl_random_pseudo_bytes($len, $strong);
if($strong === true) {
return $rnd;
}
}
/* Either we dont have the OpenSSL library or the data returned was not
* considered secure. Fall back on this less secure code. */
$rnd = '';
for ($i=0;$i<$len;$i++) {
$sha = hash('sha256', mt_rand());
$char = mt_rand(0,30);
$rnd .= chr(hexdec($sha[$char].$sha[$char+1]));
}
return (binary) $rnd;
}
The first part is simple. If we have the openssl_random_pseudo_bytes() function available, we try to use it. If it produces secure output we just use that.
If not we need to produce our own randomness. This is produced with the following code:
$rnd = '';
for ($i=0;$i<$len;$i++) {
$sha = hash('sha256', mt_rand());
$char = mt_rand(0,30);
$rnd .= chr(hexdec($sha[$char].$sha[$char+1]));
}
It may look a bit confusing, But it's really not. What we do is to create a sha256 hash from a random value, then we use two random characters of this hash to produce a random character.
Copyright (c) 2011, 2012 Audun Larsen.
Drupal theme by Kiwi Themes.
