Esempio n. 1
0
 /**
  * Makes sure that the PRNG has been seeded with a fairly secure value
  *
  * @static
  * @access private
  * @return void
  */
 private static function seedRandom()
 {
     static $seeded = FALSE;
     if ($seeded) {
         return TRUE;
     }
     $bytes = NULL;
     //
     // On linux/unix/solaris we should be able to use /dev/urandom
     //
     if (!self::checkOS('windows') && ($handle = fopen('/dev/urandom', 'rb'))) {
         $bytes = fread($handle, 4);
         fclose($handle);
         //
         // On windows we should be able to use the Cryptographic Application Programming Interface COM object
         //
     } elseif (self::checkOS('windows') && class_exists('COM', FALSE)) {
         try {
             // This COM object no longer seems to work on PHP 5.2.9+, no response on the bug report yet
             $capi = new COM('CAPICOM.Utilities.1');
             $bytes = base64_decode($capi->getrandom(4, 0));
             unset($capi);
         } catch (Exception $e) {
         }
     }
     //
     // If we could not use the OS random number generators we get some of the most unique info we can
     //
     if (!$bytes) {
         $string = microtime(TRUE) . uniqid('', TRUE) . join('', stat(__FILE__)) . disk_free_space(dirname(__FILE__));
         $bytes = substr(pack('H*', md5($string)), 0, 4);
     }
     $seed = (int) (base_convert(bin2hex($bytes), 16, 10) - 2147483647);
     mt_srand($seed);
     return $seeded = TRUE;
 }
Esempio n. 2
0
 /**
  * Makes sure that the PRNG has been seeded with a fairly secure value
  * 
  * @return void
  */
 private static function seedRandom()
 {
     static $seeded = FALSE;
     if ($seeded) {
         return;
     }
     $old_level = error_reporting(error_reporting() & ~E_WARNING);
     $bytes = NULL;
     // On linux/unix/solaris we should be able to use /dev/urandom
     if (!fCore::checkOS('windows') && ($handle = fopen('/dev/urandom', 'rb'))) {
         $bytes = fread($handle, 32);
         fclose($handle);
         // On windows we should be able to use the Cryptographic Application Programming Interface COM object
     } elseif (fCore::checkOS('windows') && class_exists('COM', FALSE)) {
         try {
             // This COM object no longer seems to work on PHP 5.2.9+, no response on the bug report yet
             $capi = new COM('CAPICOM.Utilities.1');
             $bytes = base64_decode($capi->getrandom(32, 0));
             unset($capi);
         } catch (Exception $e) {
         }
     }
     // If we could not use the OS random number generators we get some of the most unique info we can
     if (!$bytes) {
         $bytes = microtime(TRUE) . uniqid('', TRUE) . join('', stat(__FILE__)) . disk_free_space(__FILE__);
     }
     error_reporting($old_level);
     $seed = md5($bytes);
     $seed = base_convert($seed, 16, 10);
     $seed = (double) substr($seed, 0, 13) + (double) substr($seed, 14, 13);
     mt_srand($seed);
     $seeded = TRUE;
 }
 /**
  * This method will generate strong random data for cryptographic use.
  *
  * @param int $length
  * @return binary
  */
 public static function getRandomBytes($length)
 {
     $length = (int) $length;
     if ($length < 1) {
         throw new Exception('Length cannot be less than 1.');
     }
     // Works on systems that have OpenSSL installed and OpenSSL extension loaded.
     if (function_exists('openssl_random_pseudo_bytes')) {
         $random = openssl_random_pseudo_bytes($length, $strong);
         if ($strong) {
             return (string) $random;
         }
     }
     // Only execute on unix based systems
     if (DIRECTORY_SEPARATOR === '/') {
         // Works on Sun Solaris, Unix and Linux systems.
         $fp = @fopen('/dev/urandom', 'rb');
         if ($fp) {
             $random = fread($fp, $length);
             fclose($fp);
             return (string) $random;
         }
     }
     // Works on Windows x86.
     if (class_exists('COM')) {
         try {
             $csp = new COM('CAPICOM.Utilities.1');
             // We are stripping because sometimes the method appends newlines?
             $random = substr((string) base64_decode($csp->getrandom($length, 0)), 0, $length);
             unset($csp);
             return (string) $random;
         } catch (Exception $e) {
         }
     }
     // PHP has a bug that prevents you from creating a byte array via variants. Thus, no CSP support for Windows x64.
     // If someone is able to circumvent this problem, please email me.
     // Could work on Windows x64.
     if (false) {
         if (class_exists('DOTNET')) {
             try {
                 $csp = new DOTNET("mscorlib", "System.Security.Cryptography.RNGCryptoServiceProvider");
                 $array = array_fill(0, $length, null);
                 $variant = new VARIANT($array, VT_ARRAY | VT_UI1);
                 $csp->GetBytes($variant);
                 unset($csp);
                 return (string) implode('', $array);
             } catch (Exception $e) {
             }
         }
     }
     // This is random data from OpenSSL that was marked as "weak". It's better than mt_rand().
     if (isset($random)) {
         return (string) $random;
     }
     // Falling back to PHP's mt_rand() and the rest if nothing worked.
     // This basically means we are either on a Windows x64 system without OpenSSL or on a really weird system. :|
     $random = '';
     $backtrace = debug_backtrace();
     $stat = stat($backtrace[0]['file']);
     // Using the name of the caller script.
     for ($a = 0; $a < $length; $a++) {
         // Since we can't use any good random generators, we need to use as many poor "random" sources as possible.
         $source = mt_rand();
         // Weak pseudo random.
         $source += microtime(true);
         // Non-random and is poor in tight loops - yes, like this one.
         // $source += uniqid('', true); // The only real reason to use uniqid() here is due to its use of the internal LCG.
         $source += memory_get_usage();
         // Has a weak avalance effect and is predictable.
         $source += getmypid();
         // Non-random and doesn't change until the next request.
         $source += $stat[7] + substr($stat[8], -3, 3) + substr($stat[9], -3, 3) + substr($stat[10], -3, 3);
         // File stats.
         // Let's make it a byte.
         $random .= chr($source % 255);
     }
     return (string) $random;
 }