diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php index 3251ce8cc2f22d2b9c9517d02c7d200addce2266..b7b5c35f94374658867e08413f950af3147d7ccd 100644 --- a/lib/SimpleSAML/Utilities.php +++ b/lib/SimpleSAML/Utilities.php @@ -177,11 +177,10 @@ class SimpleSAML_Utilities { } public static function generateID() { - $length = 42; - $key = "_"; - for ( $i=0; $i < $length; $i++ ) - { - $key .= dechex( rand(0,15) ); + $bytes = self::generateRandomBytes(21); + $key = '_'; + for($i = 0; $i < 21; $i++) { + $key .= sprintf('%02x', ord($bytes[$i])); } return $key; } @@ -881,6 +880,43 @@ class SimpleSAML_Utilities { return $userid; } + + /** + * This function generates a binary string containing random bytes. + * + * It will use /dev/urandom if available, and fall back to the builtin mt_rand()-function if not. + * + * @param $length The number of random bytes to return. + * @return A string of lenght $length with random bytes. + */ + public static function generateRandomBytes($length) { + static $fp = NULL; + assert('is_int($length)'); + + if($fp === NULL) { + $fp = @fopen('/dev/urandom', 'rb'); + } + + if($fp !== FALSE) { + /* Read random bytes from /dev/urandom. */ + $data = fread($fp, $length); + if($data === FALSE) { + throw new Exception('Error reading random data.'); + } + if(strlen($data) != $length) { + throw new Exception('Did not get requested number of bytes from random source.'); + } + } else { + /* Use mt_rand to generate $length random bytes. */ + $data = ''; + for($i = 0; $i < $length; $i++) { + $data .= chr(mt_rand(0, 255)); + } + } + + return $data; + } + } ?> \ No newline at end of file