public function filter($value)
 {
     //source: http://www.php-security.org/2010/05/09/mops-submission-04-generating-unpredictable-session-ids-and-hashes/
     $entropy = '';
     // try ssl first
     if (function_exists('openssl_random_pseudo_bytes')) {
         $entropy = openssl_random_pseudo_bytes(64, $strong);
         // skip ssl since it wasn't using the strong algo
         if ($strong !== true) {
             $entropy = '';
         }
     }
     // add some basic mt_rand/uniqid combo
     $entropy .= uniqid(mt_rand(), true);
     // try to read from the windows RNG
     if (class_exists('COM')) {
         try {
             $com = new COM('CAPICOM.Utilities.1');
             $entropy .= base64_decode($com->GetRandom(64, 0));
         } catch (Exception $ex) {
         }
     }
     // try to read from the unix RNG
     if (is_readable('/dev/urandom')) {
         $h = fopen('/dev/urandom', 'rb');
         $entropy .= fread($h, 64);
         fclose($h);
     }
     $hash = hash('whirlpool', $entropy);
     return substr($hash, 0, $this->_length);
 }
Exemplo n.º 2
0
function generateUniqueId($maxLength = null)
{
    $entropy = '';
    // On test ssl d'abord.
    if (function_exists('openssl_random_pseudo_bytes')) {
        $entropy = openssl_random_pseudo_bytes(64, $strong);
        // skip ssl since it wasn't using the strong algo
        if ($strong !== true) {
            $entropy = '';
        }
    }
    // On ajoute les basics mt_rand/uniqid combo
    $entropy .= uniqid(mt_rand(), true);
    // On test la lecture de la fenêtre RNG
    if (class_exists('COM')) {
        try {
            $com = new COM('CAPICOM.Utilities.1');
            $entropy .= base64_decode($com->GetRandom(64, 0));
        } catch (Exception $ex) {
        }
    }
    // on test la lecture de unix RNG
    if (is_readable('/dev/urandom')) {
        $h = fopen('/dev/urandom', 'rb');
        $entropy .= fread($h, 64);
        fclose($h);
    }
    $hash = hash('whirlpool', $entropy);
    if ($maxLength) {
        return substr($hash, 0, $maxLength);
    }
    return $hash;
}
Exemplo n.º 3
0
 public static function generate($maxLength = null)
 {
     $entropy = '';
     // try ssl first
     if (function_exists('openssl_random_pseudo_bytes')) {
         $entropy = openssl_random_pseudo_bytes(64, $strong);
         // skip ssl since it wasn't using the strong algo
         if ($strong !== true) {
             $entropy = '';
         }
     }
     // add some basic mt_rand/uniqid combo
     $entropy .= uniqid(mt_rand(), true);
     // try to read from the windows RNG
     if (class_exists('COM')) {
         try {
             $com = new COM('CAPICOM.Utilities.1');
             $entropy .= base64_decode($com->GetRandom(64, 0));
         } catch (Exception $ex) {
         }
     }
     // try to read from the unix RNG
     if (is_readable('/dev/urandom')) {
         $h = fopen('/dev/urandom', 'rb');
         $entropy .= fread($h, 64);
         fclose($h);
     }
     $hash = hash('whirlpool', $entropy);
     if ($maxLength) {
         return substr($hash, 0, $maxLength);
     }
     return $hash;
 }
Exemplo n.º 4
0
 function getRandomBytes($count)
 {
     $output = '';
     // we will try to obtain entropy from several sources, starting with OpenSSL
     if (function_exists('openssl_random_pseudo_bytes')) {
         $strong = FALSE;
         $output = openssl_random_pseudo_bytes($count, $strong);
         // if OpenSSL didn't use a strong cryptographic primitive, we'll find another source of entropy
         if (FALSE == $strong) {
             $output = '';
         }
     }
     // if we've got a POSIX system, hopefully urandom is available
     if ($fd = @fopen('/dev/urandom', 'rb')) {
         $output = fread($fd, $count);
         fclose($fd);
     }
     // if we're on Windows, hopefully we can use its PRNG
     if (class_exists('COM')) {
         @($com = new COM('CAPICOM.Utilities.1'));
         @($output .= base64_decode($com->GetRandom($count, 0)));
     }
     // we fall back to a rather cryptographically insufficient but workable source of entropy
     if (strlen($output) < $count) {
         $output = '';
         for ($i = 0; $i < $count; $i += 16) {
             $this->randomState = md5(microtime() . $this->randomState);
             $output .= md5($this->randomState, TRUE);
         }
         $output = substr($output, 0, $count);
     }
     return $output;
 }
Exemplo n.º 5
0
/**
 * Windows with PHP < 5.3.0 will not have the function
 * openssl_random_pseudo_bytes() available, so let's use
 * CAPICOM to work around this deficiency.
 * 
 * @param int $bytes
 * 
 * @throws Exception
 * 
 * @return string
 */
function random_bytes($bytes)
{
    if (!is_int($bytes)) {
        throw new TypeError('Length must be an integer');
    }
    if ($bytes < 1) {
        throw new Error('Length must be greater than 0');
    }
    $buf = '';
    $util = new COM('CAPICOM.Utilities.1');
    $execCount = 0;
    /**
     * Let's not let it loop forever. If we run N times and fail to
     * get N bytes of random data, then CAPICOM has failed us.
     */
    do {
        $buf .= base64_decode($util->GetRandom($bytes, 0));
        if (RandomCompat_strlen($buf) >= $bytes) {
            /**
             * Return our random entropy buffer here:
             */
            return RandomCompat_substr($buf, 0, $bytes);
        }
        ++$execCount;
    } while ($execCount < $bytes);
    /**
     * If we reach here, PHP has failed us.
     */
    throw new Exception('PHP failed to generate random data.');
}
Exemplo n.º 6
0
function zen_get_entropy($seed)
{
    $entropy = '';
    $fp = @fopen('/dev/urandom', 'rb');
    if ($fp !== FALSE) {
        $entropy .= @fread($fp, 16);
        // echo "USING /dev/random" . "<br>";
        @fclose($fp);
    }
    // MS-Windows platform?
    if (@class_exists('COM')) {
        // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
        try {
            $CAPI_Util = new COM('CAPICOM.Utilities.1');
            $entropy .= $CAPI_Util->GetRandom(16, 0);
            if ($entropy) {
                $entropy = md5($entropy, TRUE);
                // echo "USING WINDOWS" . "<br>";
            }
        } catch (Exception $ex) {
            // echo 'Exception: ' . $ex->getMessage();
        }
    }
    if (strlen($entropy) < 16) {
        $entropy = sha1_file('/includes/configure.php');
        $entropy .= microtime() . mt_rand() . $seed;
        // echo "USING FALLBACK" . "<br>";
    }
    return sha1($entropy);
}
Exemplo n.º 7
0
 /**
  * Generate a random string of the specified size
  *
  * @param int $size The size of the requested random string
  *
  * @return string A string of the requested size
  */
 public function generate($size)
 {
     try {
         $util = new \COM('CAPICOM.Utilities.1');
         $data = base64_decode($util->GetRandom($size, 0));
         return str_pad($data, $size, chr(0));
     } catch (\Exception $e) {
         unset($e);
         return static::emptyValue($size);
     }
 }
Exemplo n.º 8
0
 public static function RandomBytes($count, $printable = FALSE)
 {
     $bytes = '';
     // supress warnings when open_basedir restricts access to /dev/urand
     if (@is_readable('/dev/urandom') && ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
         $bytes = fread($hRand, $count);
         fclose($hRand);
     }
     if (strlen($bytes) < $count && function_exists('mcrypt_create_iv')) {
         // Use MCRYPT_RAND on Windows hosts with PHP < 5.3.7, otherwise use MCRYPT_DEV_URANDOM
         // (http://bugs.php.net/55169).
         if (version_compare(PHP_VERSION, '5.3.7', '<') && strncasecmp(PHP_OS, 'WIN', 3) == 0) {
             $bytes = mcrypt_create_iv($count, MCRYPT_RAND);
         } else {
             $bytes = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
         }
     }
     if (strlen($bytes) < $count && function_exists('openssl_random_pseudo_bytes')) {
         $bytes = openssl_random_pseudo_bytes($count);
     }
     if (strlen($bytes) < $count && @class_exists('COM')) {
         // Officially deprecated in Windows 7
         // http://msdn.microsoft.com/en-us/library/aa388182%28v=vs.85%29.aspx
         try {
             $CAPI_Util = new COM('CAPICOM.Utilities.1');
             if (is_callable(array($CAPI_Util, 'GetRandom'))) {
                 $bytes = $CAPI_Util->GetRandom(16, 0);
                 $bytes = base64_decode($bytes);
             }
         } catch (Exception $ex) {
         }
     }
     if (strlen($bytes) < $count) {
         // This fallback here based on phpass code
         $bytes = '';
         $random_state = microtime();
         if (function_exists('getmypid')) {
             $random_state .= getmypid();
         }
         for ($i = 0; $i < $count; $i += 16) {
             $random_state = md5(microtime() . $random_state);
             $bytes .= pack('H*', md5($random_state));
         }
         $bytes = substr($bytes, 0, $count);
     }
     if ($printable) {
         return base64_encode($bytes);
     } else {
         return $bytes;
     }
 }
Exemplo n.º 9
0
 /**
  * Generate a random string of the specified size
  *
  * @param int $size The size of the requested random string
  *
  * @return string A string of the requested size
  */
 public function generate($size)
 {
     if (!class_exists('\\COM', false)) {
         return str_repeat(chr(0), $size);
     }
     try {
         $util = new \COM('CAPICOM.Utilities.1');
         $data = base64_decode($util->GetRandom($size, 0));
         return str_pad($data, $size, chr(0));
     } catch (\Exception $e) {
         unset($e);
         return str_repeat(chr(0), $size);
     }
 }
Exemplo n.º 10
0
 public function randomBytes($byteLength)
 {
     if (function_exists('openssl_random_pseudo_bytes')) {
         $data = openssl_random_pseudo_bytes($byteLength);
     } elseif (is_readable('/dev/urandom')) {
         $fp = @fopen('/dev/urandom', 'rb');
         if ($fp !== false) {
             $data = fread($fp, $byteLength);
             fclose($fp);
         }
     } elseif (class_exists('COM')) {
         // @TODO: Someone care to test on Windows? Not it!
         try {
             $capi = new COM('CAPICOM.Utilities.1');
             $data = $capi->GetRandom($btyeLength, 0);
         } catch (Exception $ex) {
             // Fail silently
         }
     }
     return $data;
 }
 /**
  * Note: Returned values are not guaranteed to be crypto-safe,
  * depending on the used retrieval method.
  *
  * @return string Returns a random series of bytes
  */
 public function generateEntropy()
 {
     $isWin = preg_match('/WIN/', PHP_OS);
     // TODO Fails with "Could not gather sufficient random data" on IIS, temporarily disabled on windows
     if (!$isWin) {
         if (function_exists('mcrypt_create_iv')) {
             $e = mcrypt_create_iv(64, MCRYPT_DEV_URANDOM);
             if ($e !== false) {
                 return $e;
             }
         }
     }
     // Fall back to SSL methods - may slow down execution by a few ms
     if (function_exists('openssl_random_pseudo_bytes')) {
         $e = openssl_random_pseudo_bytes(64, $strong);
         // Only return if strong algorithm was used
         if ($strong) {
             return $e;
         }
     }
     // Read from the unix random number generator
     if (!$isWin && !ini_get('open_basedir') && is_readable('/dev/urandom') && ($h = fopen('/dev/urandom', 'rb'))) {
         $e = fread($h, 64);
         fclose($h);
         return $e;
     }
     // Warning: Both methods below are considered weak
     // try to read from the windows RNG
     if ($isWin && class_exists('COM')) {
         try {
             $comObj = new COM('CAPICOM.Utilities.1');
             if (is_callable(array($comObj, 'GetRandom'))) {
                 return base64_decode($comObj->GetRandom(64, 0));
             }
         } catch (Exception $ex) {
         }
     }
     // Fallback to good old mt_rand()
     return uniqid(mt_rand(), true);
 }
/**
 * Returns entropy using a hash of various available methods for obtaining
 * random data.
 * The default hash method is "sha1" and the default size is 32.
 *
 * @param string $hash
 *          the hash method to use while generating the hash.
 * @param int $size
 *          the size of random data to use while generating the hash.
 * @return string the randomized salt
 */
function zen_get_entropy($hash = 'sha1', $size = 32)
{
    $data = null;
    if (!in_array($hash, hash_algos())) {
        $hash = 'sha1';
    }
    if (!is_int($size)) {
        $size = (int) $size;
    }
    // Use openssl if available
    if (function_exists('openssl_random_pseudo_bytes')) {
        // echo('Attempting to create entropy using openssl');
        $entropy = openssl_random_pseudo_bytes($size, $strong);
        if ($strong) {
            $data = $entropy;
        }
        unset($strong, $entropy);
    }
    // Use mcrypt with /dev/urandom if available
    if ($data === null && function_exists('mcrypt_create_iv') && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || version_compare(PHP_VERSION, '5.3.7', '>='))) {
        // echo('Attempting to create entropy using mcrypt');
        $entropy = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM);
        if ($entropy !== FALSE) {
            $data = $entropy;
        }
        unset($entropy);
    }
    if ($data === null) {
        // Fall back to using /dev/urandom if available
        $fp = @fopen('/dev/urandom', 'rb');
        if ($fp !== FALSE) {
            // echo('Attempting to create entropy using /dev/urandom');
            $entropy = @fread($fp, $size);
            @fclose($fp);
            if (strlen($entropy) == $size) {
                $data = $entropy;
            }
            unset($fp, $entropy);
        }
    }
    // Final fallback (mixture of various methods)
    if ($data === null) {
        // echo('Attempting to create entropy using FINAL FALLBACK');
        if (!defined('DIR_FS_ROOT')) {
            define('DIR_FS_ROOT', DIR_FS_CATALOG);
        }
        $filename = DIR_FS_ROOT . 'includes/configure.php';
        $stat = @stat($filename);
        if ($stat === FALSE) {
            $stat = array('microtime' => microtime());
        }
        $stat['mt_rand'] = mt_rand();
        $stat['file_hash'] = hash_file($hash, $filename, TRUE);
        // Attempt to get a random value on windows
        // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
        if (@class_exists('COM')) {
            try {
                $CAPI_Util = new COM('CAPICOM.Utilities.1');
                $entropy = $CAPI_Util->GetRandom($size, 0);
                if ($entropy) {
                    // echo('Adding random data to entropy using CAPICOM.Utilities');
                    $stat['CAPICOM_Utilities_random'] = md5($entropy, TRUE);
                }
                unset($CAPI_Util, $entropy);
            } catch (Exception $ex) {
            }
        }
        // echo('Adding random data to entropy using file information and contents');
        @shuffle($stat);
        foreach ($stat as $value) {
            $data .= $value;
        }
        unset($filename, $value, $stat);
    }
    return hash($hash, $data);
}
Exemplo n.º 13
0
 /**
  * Windows with PHP < 5.3.0 will not have the function
  * openssl_random_pseudo_bytes() available, so let's use
  * CAPICOM to work around this deficiency.
  * 
  * @param int $bytes
  * @return string
  */
 function random_bytes($bytes)
 {
     try {
         $buf = '';
         $util = new COM('CAPICOM.Utilities.1');
         $execs = 0;
         /**
          * Let's not let it loop forever. If we run N times and fail to
          * get N bytes of random data, then CAPICOM has failed us.
          */
         do {
             $buf .= base64_decode($util->GetRandom($bytes, 0));
             if (RandomCompat_strlen($buf) >= $bytes) {
                 return RandomCompat_substr($buf, 0, $bytes);
             }
             ++$execs;
         } while ($execs < $bytes);
     } catch (Exception $e) {
         unset($e);
         // Let's not let CAPICOM errors kill our app
     }
     throw new Exception('PHP failed to generate random data.');
 }
Exemplo n.º 14
0
function generate_random_string($chars = 16)
{
    if (defined('USE_POOR_RANDOMS')) {
        $options = array_merge(range('a', 'b'), range('A', 'Z'), range(0, 9));
        $res = '';
        for ($i = 0; $i < $chars; $i++) {
            $res .= $options[rand(0, count($options) - 1)];
        }
        return $res;
    }
    $pr_bits = '';
    if (function_exists('openssl_random_pseudo_bytes')) {
        $pr_bits = openssl_random_pseudo_bytes($chars);
    } else {
        // Unix/Linux platform?
        $fp = @fopen('/dev/urandom', 'rb');
        if ($fp !== FALSE) {
            $pr_bits .= @fread($fp, $chars);
            @fclose($fp);
        }
        // MS-Windows platform?
        if (@class_exists('COM')) {
            // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
            try {
                $CAPI_Util = new COM('CAPICOM.Utilities.1');
                $pr_bits .= $CAPI_Util->GetRandom($chars, 0);
                // if we ask for binary data PHP munges it, so we
                // request base64 return value.  We squeeze out the
                // redundancy and useless ==CRLF by hashing...
                if ($pr_bits) {
                    $pr_bits = md5($pr_bits, TRUE);
                }
            } catch (Exception $ex) {
                // echo 'Exception: ' . $ex->getMessage();
            }
        }
    }
    if (empty($pr_bits)) {
        trigger_error("Could not generate random string", E_USER_ERROR);
    }
    if (strlen($pr_bits) < $chars) {
        trigger_error("Generated random string not long enough (only " . strlen($pr_bits));
    }
    $validChars = array_merge(range(0, 9), range('A', 'Z'), range('a', 'z'));
    for ($i = 0; $i < strlen($pr_bits); $i++) {
        if (!preg_match('/[A-Za-z0-9]/', $pr_bits[$i])) {
            $pr_bits[$i] = $validChars[ord($pr_bits[$i]) % count($validChars)];
        }
    }
    return $pr_bits;
}
Exemplo n.º 15
0
/**
 * Return truly (pseudo) random bytes if available, otherwise fall back to mt_rand
 *
 * @author Mark Seecof
 * @author Michael Hamann <*****@*****.**>
 * @link   http://www.php.net/manual/de/function.mt-rand.php#83655
 * @param int $length number of bytes to get
 * @return string binary random strings
 */
function auth_randombytes($length)
{
    $strong = false;
    $rbytes = false;
    if (function_exists('openssl_random_pseudo_bytes') && (version_compare(PHP_VERSION, '5.3.4') >= 0 || strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
        $rbytes = openssl_random_pseudo_bytes($length, $strong);
    }
    if (!$strong && function_exists('mcrypt_create_iv') && (version_compare(PHP_VERSION, '5.3.7') >= 0 || strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
        $rbytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
        if ($rbytes !== false && strlen($rbytes) === $length) {
            $strong = true;
        }
    }
    // If no strong randoms available, try OS the specific ways
    if (!$strong) {
        // Unix/Linux platform
        $fp = @fopen('/dev/urandom', 'rb');
        if ($fp !== false) {
            $rbytes = fread($fp, $length);
            fclose($fp);
        }
        // MS-Windows platform
        if (class_exists('COM')) {
            // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
            try {
                $CAPI_Util = new COM('CAPICOM.Utilities.1');
                $rbytes = $CAPI_Util->GetRandom($length, 0);
                // if we ask for binary data PHP munges it, so we
                // request base64 return value.
                if ($rbytes) {
                    $rbytes = base64_decode($rbytes);
                }
            } catch (Exception $ex) {
                // fail
            }
        }
    }
    if (strlen($rbytes) < $length) {
        $rbytes = false;
    }
    // still no random bytes available - fall back to mt_rand()
    if ($rbytes === false) {
        $rbytes = '';
        for ($i = 0; $i < $length; ++$i) {
            $rbytes .= chr(mt_rand(0, 255));
        }
    }
    return $rbytes;
}
Exemplo n.º 16
0
 /**
  * Returns a string of highly randomized bytes (over the full 8-bit range).
  *
  * @copyright	Drupal CMS
  * @license		GNU General Public License version 2
  * @param		integer  Number of characters (bytes) to return
  * @return		string   Random Bytes
  */
 public static function generateRandomBytes($count)
 {
     $output = '';
     // /dev/urandom is available on many *nix systems and is considered
     // the best commonly available pseudo-random source.
     if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) {
         $output = fread($fh, $count);
         fclose($fh);
     } elseif (TYPO3_OS == 'WIN') {
         if (class_exists('COM')) {
             try {
                 $com = new COM('CAPICOM.Utilities.1');
                 $output = base64_decode($com->GetRandom($count, 0));
             } catch (Exception $e) {
                 // CAPICOM not installed
             }
         }
         if ($output === '' && version_compare(PHP_VERSION, '5.3.0', '>=')) {
             if (function_exists('mcrypt_create_iv')) {
                 $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
             } elseif (function_exists('openssl_random_pseudo_bytes')) {
                 $isStrong = NULL;
                 $output = openssl_random_pseudo_bytes($count, $isStrong);
                 // skip ssl since it wasn't using the strong algo
                 if ($isStrong !== TRUE) {
                     $output = '';
                 }
             }
         }
     }
     // fallback if other random byte generation failed until now
     if (!isset($output[$count - 1])) {
         // We initialize with the somewhat random.
         $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . base_convert(memory_get_usage() % pow(10, 6), 10, 2) . microtime() . uniqid('') . getmypid();
         while (!isset($output[$count - 1])) {
             $randomState = sha1(microtime() . mt_rand() . $randomState);
             $output .= sha1(mt_rand() . $randomState, TRUE);
         }
         $output = substr($output, strlen($output) - $count, $count);
     }
     return $output;
 }
Exemplo n.º 17
0
 /**
  * Uses Windows API to generate a secure password. We basically generate
  * a random number of $len bytes and convert the resulting binary string
  * to something user readable.
  *
  * This relies on the now obsolete CAPICOM library from MS:
  * http://www.microsoft.com/en-us/download/details.aspx?id=25281
  * Which is no longer supported after Vista. It was replaced with the
  * .net x509 crypto lib.
  *
  * Helper for generate().
  *
  * @param int $len - strength of the password in bytes
  *
  * @return a printable password string
  * */
 private function tryWindows($len)
 {
     $pr_bits = "";
     if (@class_exists('COM')) {
         // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
         try {
             $CAPI_Util = new COM('CAPICOM.Utilities.1');
             $pr_bits .= $CAPI_Util->GetRandom($len, 0);
             // if we ask for binary data PHP munges it, so we
             // request base64 return value.  We squeeze out the
             // redundancy and useless ==CRLF by hashing...
             if ($pr_bits) {
                 $pr_bits = $this->binconvert($pr_bits, true);
             }
         } catch (Exception $ex) {
             return "";
         }
     }
     return $pr_bits;
 }
Exemplo n.º 18
0
 public function entropy($size = 23)
 {
     // use mcrypt with urandom if we're on 5.3+
     if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
         return mcrypt_create_iv($size, MCRYPT_DEV_URANDOM);
     }
     // otherwise try ssl (beware - it may slow down your app by a few milliseconds)
     if (function_exists('openssl_random_pseudo_bytes')) {
         $entropy = openssl_random_pseudo_bytes($size, $strong);
         // skip ssl since it wasn't using the strong algo
         if ($strong) {
             return $entropy;
         }
     }
     // try to read from the unix RNG
     if (is_readable('/dev/urandom') && ($handle = fopen('/dev/urandom', 'rb'))) {
         $entropy = fread($handle, $size);
         fclose($handle);
         return $entropy;
     }
     // Warning !
     // from here on, the entropy is considered weak
     // so you may want to consider just throwing
     // an exception to realize that your code is running
     // in an insecure way
     // try to read from the windows RNG
     if (class_exists('COM', FALSE)) {
         try {
             $com = new \COM('CAPICOM.Utilities.1');
             $entropy = base64_decode($com->GetRandom($size, 0));
             return $entropy;
         } catch (Exception $e) {
             throw new \ErrorException($e);
         }
     }
     // last solution.. barely better than nothing
     return substr(uniqid(mt_rand(), true), $size);
 }
Exemplo n.º 19
0
 /**
  * Read random bytes from /dev/urandom or equivalent. See also
  * @{method:readRandomCharacters}.
  *
  * @param   int     Number of bytes to read.
  * @return  string  Random bytestring of the provided length.
  *
  * @task file
  *
  * @phutil-external-symbol class COM
  */
 public static function readRandomBytes($number_of_bytes)
 {
     if (phutil_is_windows()) {
         if (!class_exists('COM')) {
             throw new FilesystemException('CAPICOM.Utilities.1', "Class 'COM' does not exist, you must enable php_com_dotnet.dll.");
         }
         try {
             $com = new COM('CAPICOM.Utilities.1');
         } catch (Exception $ex) {
             throw new FilesystemException('CAPICOM.Utilities.1', 'Unable to load DLL, follow instructions at ' . 'https://bugs.php.net/48498.');
         }
         try {
             return $com->GetRandom($number_of_bytes);
         } catch (Exception $ex) {
             throw new FilesystemException('CAPICOM.Utilities.1', 'Unable to read random bytes through CAPICOM!');
         }
     }
     $urandom = @fopen('/dev/urandom', 'rb');
     if (!$urandom) {
         throw new FilesystemException('/dev/urandom', 'Failed to open /dev/urandom for reading!');
     }
     $data = @fread($urandom, $number_of_bytes);
     if (strlen($data) != $number_of_bytes) {
         throw new FilesystemException('/dev/urandom', 'Failed to read random bytes!');
     }
     @fclose($urandom);
     return $data;
 }
Exemplo n.º 20
0
 /** {@inheritDoc} */
 public function generateSalt()
 {
     $api = new COM('CAPICOM.Utilities.1');
     return $this->processSalt($api->GetRandom(22, 0));
 }
Exemplo n.º 21
0
 public static function secureRandom($bits = 16)
 {
     $bytes = $bits / 8;
     $result = '';
     $digits = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
     $pr_bits = '';
     #Unix/Linux platform
     try {
         $fp = @fopen('/dev/urandom', 'rb');
         if ($fp !== false) {
             $pr_bits .= @fread($fp, $bytes);
             @fclose($fp);
         }
     } catch (Exception $e) {
     }
     #MS-Windows platform before CAPICOM discontinued
     if (@class_exists('COM')) {
         #http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
         try {
             $CAPI_Util = new COM('CAPICOM.Utilities.1');
             $pr_bits .= $CAPI_Util->GetRandom($bytes, 0);
             #ask for binary data PHP munges it, so we
             #request base64 return value.  We squeeze out the
             #redundancy and useless ==CRLF by hashing...
             if ($pr_bits) {
                 $pr_bits = md5($pr_bits, true);
             }
         } catch (Exception $e) {
         }
     }
     #nothing has worked yet so lets make an outside connection
     if (strlen($pr_bits) < $bytes) {
         try {
             $pr_bits = file_get_contents("http://www.random.org/cgi-bin/randbyte?nbytes={$bytes}&format=h");
             #connect to random.org for the random stuff
             $pr_bits = preg_replace('/[^0-9A-z]/', '', trim($pr_bits));
             #git rid of the spaces, only leaves the 16 bits or 32 characters
             $pr_bits = pack("H*", $pr_bits);
             #pack it down into the 16 byte string
         } catch (Exception $e) {
         }
     }
     #failed to get any random source to work
     if (strlen($pr_bits) < $bytes) {
         throw new NoRandomProviderException();
         return false;
     }
     $len = strlen($pr_bits);
     $b = 0;
     for ($i = 0; $i < $len; $i++) {
         $b = ord($pr_bits[$i]);
         $result = $result . $digits[($b & 0xf0) >> 4];
         $result = $result . $digits[$b & 0xf];
     }
     return $result;
 }
Exemplo n.º 22
0
 /**
  * Returns a random "salt" value, to be used when "hashing" a password
  * using a one-way encryption algorithm, to prevent an attack using a "rainbow table"
  * Tryes to use the best available random number generator
  * @return string The generated random "salt"
  */
 static function GetNewSalt()
 {
     // Copied from http://www.php.net/manual/en/function.mt-rand.php#83655
     // get 128 pseudorandom bits in a string of 16 bytes
     $sRandomBits = null;
     // Unix/Linux platform?
     $fp = @fopen('/dev/urandom', 'rb');
     if ($fp !== FALSE) {
         //echo "Random bits pulled from /dev/urandom<br/>\n";
         $sRandomBits .= @fread($fp, 16);
         @fclose($fp);
     } else {
         // MS-Windows platform?
         if (@class_exists('COM')) {
             // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
             try {
                 $CAPI_Util = new COM('CAPICOM.Utilities.1');
                 $sBase64RandomBits = '' . $CAPI_Util->GetRandom(16, 0);
                 // if we ask for binary data PHP munges it, so we
                 // request base64 return value.  We squeeze out the
                 // redundancy and useless ==CRLF by hashing...
                 if ($sBase64RandomBits) {
                     //echo "Random bits got from CAPICOM.Utilities.1<br/>\n";
                     $sRandomBits = md5($sBase64RandomBits, TRUE);
                 }
             } catch (Exception $ex) {
                 // echo 'Exception: ' . $ex->getMessage();
             }
         }
     }
     if ($sRandomBits == null) {
         // No "strong" random generator available, use PHP's built-in mechanism
         //echo "Random bits generated from mt_rand<br/>\n";
         mt_srand(crc32(microtime()));
         $sRandomBits = '';
         for ($i = 0; $i < 4; $i++) {
             $sRandomBits .= sprintf('%04x', mt_rand(0, 65535));
         }
     }
     return $sRandomBits;
 }
Exemplo n.º 23
0
/**
 * Returns a securely generated seed for PHP's RNG (Random Number Generator)
 *
 * @param int Length of the seed bytes (8 is default. Provides good cryptographic variance)
 * @return int An integer equivalent of a secure hexadecimal seed
 */
function secure_seed_rng($count = 8)
{
    $output = '';
    // DIRECTORY_SEPARATOR checks if running windows
    if (DIRECTORY_SEPARATOR != '\\') {
        // Unix/Linux
        // Use OpenSSL when available
        if (function_exists('openssl_random_pseudo_bytes')) {
            $output = openssl_random_pseudo_bytes($count);
        } elseif (function_exists('mcrypt_create_iv')) {
            $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
        } elseif (@is_readable('/dev/urandom') && ($handle = @fopen('/dev/urandom', 'rb'))) {
            $output = @fread($handle, $count);
            @fclose($handle);
        }
    } else {
        // Windows
        // Use OpenSSL when available
        // PHP <5.3.4 had a bug which makes that function unusable on Windows
        if (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
            $output = openssl_random_pseudo_bytes($count);
        } elseif (function_exists('mcrypt_create_iv')) {
            $output = mcrypt_create_iv($count, MCRYPT_RAND);
        } elseif (class_exists('COM')) {
            try {
                $CAPI_Util = new COM('CAPICOM.Utilities.1');
                if (is_callable(array($CAPI_Util, 'GetRandom'))) {
                    $output = $CAPI_Util->GetRandom($count, 0);
                }
            } catch (Exception $e) {
            }
        }
    }
    // Didn't work? Do we still not have enough bytes? Use our own (less secure) rng generator
    if (strlen($output) < $count) {
        $output = '';
        // Close to what PHP basically uses internally to seed, but not quite.
        $unique_state = microtime() . @getmypid();
        for ($i = 0; $i < $count; $i += 16) {
            $unique_state = md5(microtime() . $unique_state);
            $output .= pack('H*', md5($unique_state));
        }
    }
    // /dev/urandom and openssl will always be twice as long as $count. base64_encode will roughly take up 33% more space but crc32 will put it to 32 characters
    $output = hexdec(substr(dechex(crc32(base64_encode($output))), 0, $count));
    return $output;
}
Exemplo n.º 24
0
 /**
  * Get random bytes
  *
  * @ref https://github.com/paragonie/random_compat/
  *
  * @param  int $length Output length
  *
  * @return  string|false false on error
  */
 public static function get_random_bytes($length)
 {
     if (!$length || !ctype_digit((string) $length)) {
         return false;
     } else {
         $length = (int) $length;
     }
     if (function_exists('random_bytes') && self::is_php('7.0')) {
         /**
          * PHP 7 -> http://php.net/manual/de/function.random-bytes.php
          */
         try {
             $return = random_bytes($length);
         } catch (\Exception $e) {
             $return = false;
         }
         return $return;
     } else {
         /**
          * PHP 5.2.0 - 5.6.x way to implement random_bytes()
          *
          * // WARNING: Unfortunately, none of the following PRNGs is guaranteed to exist ...
          *
          * In order of preference:
          *   1. PHP-Module:   "mcrypt" via mcrypt_create_iv()
          *   2. Linux / BSD:  "/dev/urandom" via fread()
          *   3. Windows:      \COM('CAPICOM.Utilities.1')->GetRandom()
          *   4. PHP+OpenSSL:  openssl_random_pseudo_bytes()
          */
         /**
          * 1. PHP-Module
          */
         if (extension_loaded('mcrypt') && defined(MCRYPT_DEV_URANDOM) === true) {
             $output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
             if ($output !== false && UTF8::strlen($output, '8bit') === $length) {
                 return $output;
             }
         }
         /**
          * 2. Linux / BSD
          */
         if (!ini_get('open_basedir') && is_readable('/dev/urandom')) {
             $fp = fopen('/dev/urandom', 'rb');
             if (!empty($fp)) {
                 $st = fstat($fp);
                 // In C, this would be: (stat_mode & S_IFMT) !== S_IFCHR
                 if (($st['mode'] & 0170000) !== 020000) {
                     fclose($fp);
                     $fp = false;
                 }
                 unset($st);
             }
         }
         if (isset($fp) && $fp !== false) {
             /**
              * stream_set_read_buffer() / stream_set_chunk_size does not exist in HHVM
              *
              * If we don't set the stream's read buffer to 0, PHP will
              * internally buffer 8192 bytes, which can waste entropy
              *
              * stream_set_read_buffer returns 0 on success
              */
             if (function_exists('stream_set_chunk_size')) {
                 stream_set_chunk_size($fp, $length);
             }
             if (function_exists('stream_set_read_buffer')) {
                 stream_set_read_buffer($fp, $length);
             }
             $remaining = $length;
             $buf = '';
             do {
                 $read = fread($fp, $remaining);
                 // We cannot safely read from the file, so exit the do-while loop.
                 if ($read === false) {
                     $buf = false;
                     break;
                 }
                 // Decrease the number of bytes returned from remaining.
                 $remaining -= UTF8::strlen($read, '8bit');
                 $buf .= $read;
             } while ($remaining > 0);
             fclose($fp);
             if ($buf !== false) {
                 if (UTF8::strlen($buf, '8bit') === $length) {
                     return $buf;
                 }
             }
         }
         /*
          * 3. Windows
          *
          * PHP can be used to access COM objects on Windows platforms
          *
          * ---
          *
          * PROBLEM: you see this error-message:
          *    com_exception thrown with message
          *      "Failed to create COM object `CAPICOM.Utilities.1': Ungültige Syntax
          *
          * SOLUTION: register the dll:
          *    regsvr32 c:\windows\capicom.dll
          *
          * ---
          *
          * @ref http://php.net/manual/en/ref.com.php
          */
         if (extension_loaded('com_dotnet') && class_exists('COM') === true) {
             // init
             $buf = '';
             /** @noinspection PhpUndefinedClassInspection */
             $util = new \COM('CAPICOM.Utilities.1');
             /**
              * Let's not let it loop forever. If we run N times and fail to
              * get N bytes of random data, then CAPICOM has failed us.
              */
             $execCount = 0;
             do {
                 /** @noinspection PhpUndefinedMethodInspection */
                 $buf .= base64_decode($util->GetRandom($length, 0));
                 if (UTF8::strlen($buf, '8bit') >= $length) {
                     return UTF8::substr($buf, 0, $length);
                 }
                 ++$execCount;
             } while ($execCount < $length);
         }
         /**
          * 4. PHP + OpenSSL
          *
          * fallback to "openssl_random_pseudo_bytes()"
          */
         if (function_exists('openssl_random_pseudo_bytes')) {
             $output = openssl_random_pseudo_bytes($length, $strong);
             if ($output !== false && $strong === true) {
                 if (UTF8::strlen($output, '8bit') === $length) {
                     return $output;
                 }
             }
         }
         return false;
     }
 }
Exemplo n.º 25
0
 /**
  * Generate random bytes for high entropy
  *
  * @since 1.3.6
  *
  * @return string String of random bytes
  **/
 private function entropy()
 {
     $entropy = '';
     if (function_exists('openssl_random_pseudo_bytes')) {
         $entropy = openssl_random_pseudo_bytes(64, $strong);
         // Don't use openssl if a strong crypto algo wasn't used
         if ($strong !== true) {
             $entropy = '';
         }
     }
     $entropy .= uniqid(mt_rand(), true);
     // Check for open_basedir restrictions
     $openbasedir = false === strpos(ini_get('open_basedir'), DIRECTORY_SEPARATOR);
     // Try adding entropy from the Unix random number generator
     if ($openbasedir && @is_readable('/dev/urandom') && ($h = fopen('/dev/urandom', 'rb'))) {
         if (function_exists('stream_set_read_buffer')) {
             stream_set_read_buffer($h, 0);
         }
         $entropy .= @fread($h, 64);
         fclose($h);
     }
     // Try adding entropy from the Windows random number generator
     if (class_exists('COM')) {
         try {
             $CAPICOM = new COM('CAPICOM.Utilities.1');
             $entropy .= base64_decode($CAPICOM->GetRandom(64, 0));
         } catch (Exception $E) {
         }
     }
     return $entropy;
 }