This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mcrypt abstract mixer class
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The mcrypt abstract mixer class
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
abstract class AbstractMcryptMixer extends AbstractMixer
{
/**
* mcrypt module resource
*
* @var resource
*/
private $mcrypt;
/**
* Block size of cipher
*
* @var int
*/
private $blockSize;
/**
* Cipher initialization vector
*
* @var string
*/
private $initv;
/**
* {@inheritdoc}
*/
public static function test()
{
return extension_loaded('mcrypt');
}
/**
* @return bool
*/
public static function advisable()
{
return static::test() && PHP_VERSION_ID < 70100;
}
/**
* Construct mcrypt mixer
* @psalm-suppress UndefinedConstant
*/
public function __construct()
{
$this->mcrypt = mcrypt_module_open($this->getCipher(), '', MCRYPT_MODE_ECB, '');
$this->blockSize = mcrypt_enc_get_block_size($this->mcrypt);
$this->initv = str_repeat(chr(0), mcrypt_enc_get_iv_size($this->mcrypt));
}
/**
* Performs cleanup
*/
public function __destruct()
{
if ($this->mcrypt) {
mcrypt_module_close($this->mcrypt);
}
}
/**
* Fetch the cipher for mcrypt.
*
* @return string
*/
abstract protected function getCipher();
/**
* {@inheritdoc}
*/
protected function getPartSize()
{
return $this->blockSize;
}
/**
* {@inheritdoc}
*/
protected function mixParts1($part1, $part2)
{
if (!\is_string($part1)) {
throw new \InvalidArgumentException('Expected a string');
}
if (!\is_string($part2)) {
throw new \InvalidArgumentException('Expected a string');
}
return $this->encryptBlock($part1, $part2);
}
/**
* {@inheritdoc}
*/
protected function mixParts2($part1, $part2)
{
if (!\is_string($part1)) {
throw new \InvalidArgumentException('Expected a string');
}
if (!\is_string($part2)) {
throw new \InvalidArgumentException('Expected a string');
}
return $this->decryptBlock($part2, $part1);
}
/**
* Encrypts a block using the suppied key
*
* @param string $input Plaintext to encrypt
* @param string $key Encryption key
*
* @return string Resulting ciphertext
*/
private function encryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mcrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Derypts a block using the suppied key
*
* @param string $input Ciphertext to decrypt
* @param string $key Encryption key
*
* @return string Resulting plaintext
*/
private function decryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mdecrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Sets up the mcrypt module
*
* @param string $key
*
* @return void
*/
private function prepareCipher($key)
{
if (0 !== mcrypt_generic_init($this->mcrypt, $key, $this->initv)) {
throw new \RuntimeException('Failed to prepare mcrypt module');
}
}
}

View File

@@ -0,0 +1,191 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* An abstract mixer to implement a common mixing strategy
*
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Util;
/**
* An abstract mixer to implement a common mixing strategy
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
abstract class AbstractMixer implements \RandomLib\Mixer
{
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
abstract protected function getPartSize();
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts1($part1, $part2);
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts2($part1, $part2);
/**
* @return bool
*/
public static function advisable()
{
return static::test();
}
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array<int, string> $parts The parts to be mixed
*
* @return string The mixed result
* @psalm-suppress MixedArgument
*/
public function mix(array $parts)
{
if (empty($parts)) {
return '';
}
/** @var int $len */
$len = Util::safeStrlen($parts[0]);
/** @var array<int, array<int, string>> $parts */
$parts = $this->normalizeParts($parts);
$stringSize = \count($parts[0]);
$partsSize = \count($parts);
/** @var string $result */
$result = '';
/** @var int $offset */
$offset = 0;
for ($i = 0; $i < $stringSize; ++$i) {
/** @var string $stub */
$stub = (string) $parts[$offset][$i];
for ($j = 1; $j < $partsSize; ++$j) {
/** @var string $newKey */
$newKey = $parts[($j + $offset) % $partsSize][$i];
//Alternately mix the output for each source
if ($j % 2 == 1) {
$stub ^= $this->mixParts1($stub, $newKey);
} else {
$stub ^= $this->mixParts2($stub, $newKey);
}
}
$result .= $stub;
$offset = ($offset + 1) % $partsSize;
}
/** @var string $final */
$final = Util::safeSubstr($result, 0, $len);
return $final;
}
/**
* Normalize the part array and split it block part size.
*
* This will make all parts the same length and a multiple
* of the part size
*
* @param array<int, string> $parts The parts to normalize
*
* @return array The normalized and split parts
* @psalm-suppress MissingClosureReturnType
* @psalm-suppress UntypedParam
* @psalm-suppress MissingArgument
*/
protected function normalizeParts(array $parts)
{
if (empty($parts)) {
return $parts;
}
$blockSize = $this->getPartSize();
$callback =
/**
* @var callable $callback
* @param string $value
* @return int
*/
function ($value) {
return (int) Util::safeStrlen($value);
};
$mapped = array_map($callback, $parts);
if (count($mapped) < 1) {
return array();
}
/** @var int $maxSize */
$maxSize = count($mapped) > 1
? max($mapped)
: array_shift($mapped);
if ($maxSize % $blockSize != 0) {
$maxSize += $blockSize - ($maxSize % $blockSize);
}
foreach ($parts as &$part) {
$part = $this->str_pad($part, $maxSize, chr(0));
$part = str_split($part, $blockSize);
}
return $parts;
}
/**
* @param string $string
* @param int $size
* @param string $character
* @return string
*/
private function str_pad($string, $size, $character)
{
$start = Util::safeStrlen($string);
$inc = Util::safeStrlen($character);
for ($i = $start; $i < $size; $i+= $inc) {
$string = $string . $character;
}
return Util::safeSubstr($string, 0, $size);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* An abstract mixer to implement a common mixing strategy
*
* @category PHPSecurityLib
* @package Random
*/
abstract class AbstractSource implements \RandomLib\Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Returns a string of zeroes, useful when no entropy is available.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
protected static function emptyValue($size)
{
return (string) \str_repeat(\chr(0), $size);
}
}

View File

@@ -0,0 +1,290 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class Factory extends \SecurityLib\AbstractFactory
{
/**
* @var array<int, Mixer> A list of available random number mixing strategies
*/
protected $mixers = array();
/**
* @var array<int, Source> A list of available random number sources
*/
protected $sources = array();
/**
* Build a new instance of the factory, loading core mixers and sources
*
* @return void
*/
public function __construct()
{
$this->loadMixers();
$this->loadSources();
}
/**
* Get a generator for the requested strength
*
* @param Strength $strength The requested strength of the random number
*
* @throws \RuntimeException If an appropriate mixing strategy isn't found
*
* @return Generator The instantiated generator
*/
public function getGenerator(\SecurityLib\Strength $strength)
{
$sources = $this->findSources($strength);
$mixer = $this->findMixer($strength);
return new Generator($sources, $mixer);
}
/**
* Get a high strength random number generator
*
* High Strength keys should ONLY be used for generating extremely strong
* cryptographic keys. Generating them is very resource intensive and may
* take several minutes or more depending on the requested size.
*
* @return Generator The instantiated generator
*/
public function getHighStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::HIGH));
}
/**
* Get a low strength random number generator
*
* Low Strength should be used anywhere that random strings are needed in a
* non-cryptographical setting. They are not strong enough to be used as
* keys or salts. They are however useful for one-time use tokens.
*
* @return Generator The instantiated generator
*/
public function getLowStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::LOW));
}
/**
* Get a medium strength random number generator
*
* Medium Strength should be used for most needs of a cryptographic nature.
* They are strong enough to be used as keys and salts. However, they do
* take some time and resources to generate, so they should not be over-used
*
* @return Generator The instantiated generator
*/
public function getMediumStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::MEDIUM));
}
/**
* Get all loaded mixing strategies
*
* @return array<int, Mixer> An array of mixers
*/
public function getMixers()
{
return $this->mixers;
}
/**
* Get all loaded random number sources
*
* @return array<int, Source> An array of sources
*/
public function getSources()
{
return $this->sources;
}
/**
* Register a mixing strategy for this factory instance
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerMixer($name, $class)
{
$this->registerType(
'mixers',
__NAMESPACE__ . '\\Mixer',
$name,
$class
);
return $this;
}
/**
* Register a random number source for this factory instance
*
* Note that this class must implement the Source interface
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerSource($name, $class)
{
$this->registerType(
'sources',
__NAMESPACE__ . '\\Source',
$name,
$class
);
return $this;
}
/**
* Find a sources based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws \RuntimeException if a valid source cannot be found
*
* @return array<int, Source> The found source
*/
protected function findSources(\SecurityLib\Strength $strength)
{
/** @var array<int, Source> $sources */
$sources = array();
foreach ($this->getSources() as $source) {
if ($strength->compare($source::getStrength()) <= 0 && $source::isSupported()) {
/** @var Source $obj */
$obj = new $source();
if ($obj instanceof Source) {
$sources[] = $obj;
}
}
}
if (0 === count($sources)) {
throw new \RuntimeException('Could not find sources');
}
return $sources;
}
/**
* Find a mixer based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws \RuntimeException if a valid mixer cannot be found
*
* @return Mixer The found mixer
*/
protected function findMixer(\SecurityLib\Strength $strength)
{
/** @var Mixer|null $newMixer */
$newMixer = null;
/** @var Mixer|null $fallback */
$fallback = null;
foreach ($this->getMixers() as $mixer) {
if (!$mixer::test() || !$mixer::advisable()) {
continue;
}
if ($strength->compare($mixer::getStrength()) == 0) {
/** @var Mixer $newMixer */
$newMixer = new $mixer();
} elseif ($strength->compare($mixer::getStrength()) == 1) {
/** @var Mixer $fallback */
$fallback = new $mixer();
}
}
if (\is_null($newMixer)) {
if (\is_null($fallback)) {
throw new \RuntimeException('Could not find mixer');
} elseif (!($fallback instanceof Mixer)) {
throw new \RuntimeException('Invalid Mixer');
}
return $fallback;
} elseif (!($newMixer instanceof Mixer)) {
throw new \RuntimeException('Invalid Mixer');
}
return $newMixer;
}
/**
* Load all core mixing strategies
*
* @return void
* @psalm-suppress InvalidArgument
*/
protected function loadMixers()
{
$this->loadFiles(
__DIR__ . '/Mixer',
__NAMESPACE__ . '\\Mixer\\',
array($this, 'registerMixer')
);
}
/**
* Load all core random number sources
*
* @return void
* @psalm-suppress InvalidArgument
*/
protected function loadSources()
{
$this->loadFiles(
__DIR__ . '/Source',
__NAMESPACE__ . '\\Source\\',
array($this, 'registerSource')
);
}
}

View File

@@ -0,0 +1,386 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @author Timo Hamina
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Util;
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @author Timo Hamina
*/
class Generator
{
/**
* @const Flag for uppercase letters
*/
const CHAR_UPPER = 1;
/**
* @const Flag for lowercase letters
*/
const CHAR_LOWER = 2;
/**
* @const Flag for alpha characters (combines UPPER + LOWER)
*/
const CHAR_ALPHA = 3; // CHAR_UPPER | CHAR_LOWER
/**
* @const Flag for digits
*/
const CHAR_DIGITS = 4;
/**
* @const Flag for alpha numeric characters
*/
const CHAR_ALNUM = 7; // CHAR_ALPHA | CHAR_DIGITS
/**
* @const Flag for uppercase hexadecimal symbols
*/
const CHAR_UPPER_HEX = 12; // 8 | CHAR_DIGITS
/**
* @const Flag for lowercase hexidecimal symbols
*/
const CHAR_LOWER_HEX = 20; // 16 | CHAR_DIGITS
/**
* @const Flag for base64 symbols
*/
const CHAR_BASE64 = 39; // 32 | CHAR_ALNUM
/**
* @const Flag for additional symbols accessible via the keyboard
*/
const CHAR_SYMBOLS = 64;
/**
* @const Flag for brackets
*/
const CHAR_BRACKETS = 128;
/**
* @const Flag for punctuation marks
*/
const CHAR_PUNCT = 256;
/**
* @const Flag for upper/lower-case and digits but without "B8G6I1l|0OQDS5Z2"
*/
const EASY_TO_READ = 512;
/**
* @var Mixer The mixing strategy to use for this generator instance
*/
protected $mixer = null;
/**
* @var array<int, Source> An array of random number sources to use for this generator
*/
protected $sources = array();
/**
* @var array<int, string> The different characters, by Flag
*/
protected $charArrays = array(
self::CHAR_UPPER => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
self::CHAR_LOWER => 'abcdefghijklmnopqrstuvwxyz',
self::CHAR_DIGITS => '0123456789',
self::CHAR_UPPER_HEX => 'ABCDEF',
self::CHAR_LOWER_HEX => 'abcdef',
self::CHAR_BASE64 => '+/',
self::CHAR_SYMBOLS => '!"#$%&\'()* +,-./:;<=>?@[\]^_`{|}~',
self::CHAR_BRACKETS => '()[]{}<>',
self::CHAR_PUNCT => ',.;:',
);
/**
* @internal
* @private
* @const string Ambiguous characters for "Easy To Read" sets
*/
const AMBIGUOUS_CHARS = 'B8G6I1l|0OQDS5Z2()[]{}:;,.';
/**
* Build a new instance of the generator
*
* @param array<int, Source> $sources An array of random data sources to use
* @param Mixer $mixer The mixing strategy to use for this generator
*/
public function __construct(array $sources, Mixer $mixer)
{
foreach ($sources as $source) {
$this->addSource($source);
}
$this->mixer = $mixer;
}
/**
* Add a random number source to the generator
*
* @param Source $source The random number source to add
*
* @return Generator $this The current generator instance
*/
public function addSource(Source $source)
{
$this->sources[] = $source;
return $this;
}
/**
* Generate a random number (string) of the requested size
*
* @param int $size The size of the requested random number
*
* @return string The generated random number (string)
*/
public function generate($size)
{
$seeds = array();
foreach ($this->sources as $source) {
if ($source instanceof Source) {
$seeds[] = $source->generate($size);
}
}
return $this->mixer->mix($seeds);
}
/**
* Generate a random integer with the given range
*
* @param int $min The lower bound of the range to generate
* @param int $max The upper bound of the range to generate
*
* @return int The generated random number within the range
*/
public function generateInt($min = 0, $max = PHP_INT_MAX)
{
$tmp = (int) max($max, $min);
$min = (int) min($max, $min);
$max = $tmp;
$range = $max - $min;
if ($range == 0) {
return $max;
} elseif ($range > PHP_INT_MAX || is_float($range) || $range < 0) {
/**
* This works, because PHP will auto-convert it to a float at this point,
* But on 64 bit systems, the float won't have enough precision to
* actually store the difference, so we need to check if it's a float
* and hence auto-converted...
*/
throw new \RangeException(
'The supplied range is too great to generate'
);
}
$bits = $this->countBits($range) + 1;
$bytes = (int) \max(\ceil($bits / 8), 1);
if ($bits == 63) {
/**
* Fixes issue #22
*
* @see https://github.com/ircmaxell/RandomLib/issues/22
*/
$mask = 0x7fffffffffffffff;
} else {
$mask = (int) ((1 << $bits) - 1);
}
/**
* The mask is a better way of dropping unused bits. Basically what it does
* is to set all the bits in the mask to 1 that we may need. Since the max
* range is PHP_INT_MAX, we will never need negative numbers (which would
* have the MSB set on the max int possible to generate). Therefore we
* can just mask that away. Since pow returns a float, we need to cast
* it back to an int so the mask will work.
*
* On a 64 bit platform, that means that PHP_INT_MAX is 2^63 - 1. Which
* is also the mask if 63 bits are needed (by the log(range, 2) call).
* So if the computed result is negative (meaning the 64th bit is set), the
* mask will correct that.
*
* This turns out to be slightly better than the shift as we don't need to
* worry about "fixing" negative values.
*/
do {
$test = $this->generate($bytes);
/** @var int $result */
$result = \hexdec(\bin2hex($test)) & $mask;
} while ($result > $range);
return $result + $min;
}
/**
* Generate a random string of specified length.
*
* This uses the supplied character list for generating the new result
* string.
*
* @param int $length The length of the generated string
* @param int|string $characters String: An optional list of characters to use
* Integer: Character flags
*
* @return string The generated random string
*/
public function generateString($length, $characters = '')
{
if (is_int($characters)) {
// Combine character sets
$characters = $this->expandCharacterSets($characters);
}
if ($length == 0 || strlen($characters) == 1) {
return '';
} elseif (empty($characters)) {
// Default to base 64
$characters = $this->expandCharacterSets(self::CHAR_BASE64);
}
/**
* @var string $characters
*/
// determine how many bytes to generate
// This is basically doing floor(log(strlen($characters)))
// But it's fixed to work properly for all numbers
$len = strlen($characters);
// The max call here fixes an issue where we under-generate in cases
// where less than 8 bits are needed to represent $len
/** @var int $bytes */
$bytes = (int) ($length * ceil(($this->countBits($len)) / 8));
// determine mask for valid characters
$mask = 256 - (256 % $len);
$result = '';
do {
$rand = $this->generate($bytes);
for ($i = 0; $i < $bytes; $i++) {
if (\ord($rand[$i]) >= $mask) {
continue;
}
/** @var int $idx */
$idx = (int) ((int) \ord($rand[$i]) % (int) ($len));
$result .= (string) ($characters[$idx]);
}
} while (Util::safeStrlen($result) < $length);
// We may over-generate, since we always use the entire buffer
return Util::safeSubstr($result, 0, $length);
}
/**
* Get the Mixer used for this instance
*
* @return Mixer the current mixer
*/
public function getMixer()
{
return $this->mixer;
}
/**
* Get the Sources used for this instance
*
* @return array<int, Source> the current mixer
*/
public function getSources()
{
return $this->sources;
}
/**
* Count the minimum number of bits to represent the provided number
*
* This is basically floor(log($number, 2))
* But avoids float precision issues
*
* @param int $number The number to count
*
* @return int The number of bits
*/
protected function countBits($number)
{
$log2 = 0;
while ($number >>= 1) {
$log2++;
}
return $log2;
}
/**
* Expand a character set bitwise spec into a string character set
*
* This will also replace EASY_TO_READ characters if the flag is set
*
* @param int $spec The spec to expand (bitwise combination of flags)
*
* @return string The expanded string
*/
protected function expandCharacterSets($spec)
{
/** @var string $combined */
$combined = '';
if ($spec == self::EASY_TO_READ) {
$spec |= self::CHAR_ALNUM;
}
foreach ($this->charArrays as $flag => $chars) {
if ($flag == self::EASY_TO_READ) {
// handle this later
continue;
}
if (($spec & $flag) === $flag) {
$combined .= $chars;
}
}
if ($spec & self::EASY_TO_READ) {
// remove ambiguous characters
$combined = \str_replace(
\str_split(self::AMBIGUOUS_CHARS),
'',
$combined
);
}
return (string) \count_chars($combined, 3);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
interface Mixer
{
/**
* Return an instance of Strength indicating the strength of the mixer
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test();
/**
* Even if the mixer is available,
*
* @return bool
*/
public static function advisable();
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array $parts The parts to be mixed
*
* @return string The mixed result
*/
public function mix(array $parts);
}

View File

@@ -0,0 +1,126 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Hash extends \RandomLib\AbstractMixer
{
/**
* @var string The hash instance to use
*/
protected $hash = null;
/**
* Build the hash mixer
*
* @param string $hash The hash instance to use (defaults to sha512)
*
* @return void
*/
public function __construct($hash = 'sha512')
{
$this->hash = $hash;
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return Util::safeStrlen(hash($this->hash, '', true));
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return hash_hmac($this->hash, $part1, $part2, true);
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
return hash_hmac($this->hash, $part2, $part1, true);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use RandomLib\AbstractMcryptMixer;
use SecurityLib\Strength;
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
class McryptRijndael128 extends AbstractMcryptMixer
{
/**
* {@inheritdoc}
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* {@inheritdoc}
*/
protected function getCipher()
{
return 'rijndael-128';
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace RandomLib\Mixer;
use RandomLib\AbstractMixer;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* Class SodiumMixer
*
* @package RandomLib\Mixer
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2017 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
class SodiumMixer extends AbstractMixer
{
const SALSA20_BLOCK_SIZE = 64;
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return is_callable('sodium_crypto_stream') && is_callable('sodium_crypto_generichash');
}
/**
* @return bool
*/
public static function advisable()
{
return static::test() && !defined('HHVM_VERSION');
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return self::SALSA20_BLOCK_SIZE;
}
/**
* Mix 2 parts together using one method
*
* This method is jut a simple BLAKE2b hash of the two strings
* concatenated together
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return (string) \sodium_crypto_generichash($part1 . $part2, '', $this->getPartSize());
}
/**
* Mix 2 parts together using another different method
*
* This method is a salsa20 stream based on a hash of the two inputs
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
// Pre-hash the two inputs into a 448-bit output
/** @var string $hash */
$hash = \sodium_crypto_generichash($part1 . $part2, '', 56);
// Use salsa20 to expand into a pseudorandom string
return (string) \sodium_crypto_stream(
$this->getPartSize(),
Util::safeSubstr($hash, 0, 24),
Util::safeSubstr($hash, 0, 32)
);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class XorMixer extends \RandomLib\AbstractMixer
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return 64;
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return (string) ($part1 ^ $part2);
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
// Both mixers are identical, this is for speed, not security
return (string) ($part1 ^ $part2);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
interface Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported();
/**
* Generate a random string of the specified size
*
* Note: If the source fails to generate enough data, the result must be
* padded to the requested length.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size);
}

View File

@@ -0,0 +1,104 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class CAPICOM extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\COM', false);
}
/**
* 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)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
try {
/** @var \COM $util */
$util = new \COM('CAPICOM.Utilities.1');
if (!\method_exists($util, 'GetRandom')) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
$data = base64_decode((string) $util->GetRandom($size, 0));
return (string) str_pad($data, $size, chr(0));
} catch (\Exception $e) {
unset($e);
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class MTRand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
/**
* 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)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((mt_rand() ^ mt_rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Util;
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
final class MicroTime extends \RandomLib\AbstractSource
{
/**
* A static counter to ensure unique hashes and prevent state collisions
*
* @var int A counter
*/
private static $counter = null;
/**
* The current state of the random number generator.
*
* @var string The state of the PRNG
*/
private static $state = '';
public function __construct()
{
$state = self::$state;
if (function_exists('posix_times')) {
$state .= serialize(posix_times());
}
if (!defined('HHVM_VERSION') && function_exists('zend_thread_id')) {
$state .= zend_thread_id();
}
if (function_exists('hphp_get_thread_id')) {
$state .= hphp_get_thread_id();
}
$state .= getmypid() . memory_get_usage();
$state .= serialize($_ENV);
$state .= serialize($_SERVER);
$state .= count(debug_backtrace(false));
self::$state = hash('sha512', $state, true);
if (is_null(self::$counter)) {
list(, self::$counter) = unpack("i", Util::safeSubstr(self::$state, 0, 4));
$seed = $this->generate(Util::safeStrlen(dechex(PHP_INT_MAX)));
list(, self::$counter) = unpack("i", $seed);
}
}
/**
* 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)
{
$result = '';
/** @var string $seed */
$seed = (string) \microtime() . \memory_get_usage();
self::$state = hash('sha512', self::$state . $seed, true);
/**
* Make the generated randomness a bit better by forcing a GC run which
* should complete in a indeterminate amount of time, hence improving
* the strength of the randomness a bit. It's still not crypto-safe,
* but at least it's more difficult to predict.
*/
gc_collect_cycles();
for ($i = 0; $i < $size; $i += 8) {
$seed = self::$state .
(string) \microtime() .
(string) \pack('Ni', $i, self::counter());
self::$state = \hash('sha512', $seed, true);
/**
* We only use the first 8 bytes here to prevent exposing the state
* in its entirety, which could potentially expose other random
* generations in the future (in the same process)...
*/
$result .= Util::safeSubstr(self::$state, 0, 8);
}
return Util::safeSubstr($result, 0, $size);
}
/**
* @return int
*/
private static function counter()
{
if (self::$counter >= PHP_INT_MAX) {
self::$counter = -1 * PHP_INT_MAX - 1;
} else {
self::$counter++;
}
return self::$counter;
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class OpenSSL extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* PIE notes: Userland PRNGs are not high strength. OpenSSL is, at best, medium.
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
/**
* Prior to PHP 5.6.12 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.6.12
*/
if (PHP_VERSION_ID >= 50612) {
return new Strength(Strength::MEDIUM);
}
/**
* Prior to PHP 5.5.28 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.5.28
*/
if (PHP_VERSION_ID >= 50528 && PHP_VERSION_ID < 50600) {
return new Strength(Strength::MEDIUM);
}
/**
* Prior to PHP 5.4.44 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.4.44
*/
if (PHP_VERSION_ID >= 50444 && PHP_VERSION_ID < 50500) {
return new Strength(Strength::MEDIUM);
}
return new Strength(Strength::LOW);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return \is_callable('openssl_random_pseudo_bytes');
}
/**
* 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 ($size < 1) {
return str_repeat(chr(0), $size);
}
/**
* PIE notes: This $crypto_string argument doesn't do what people think
* it does. Original comment follows.
*
* Note, normally we would check the return of of $crypto_strong to
* ensure that we generated a good random string. However, since we're
* using this as one part of many sources a low strength random number
* shouldn't be much of an issue.
*/
return openssl_random_pseudo_bytes($size);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class Rand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
/**
* 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)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((rand() ^ rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The PHP7 Random Number Source
*
* This uses the inbuilt PHP7 Random Bytes function
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The PHP7 Random Number Source
*
* This uses the php7 secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class RandomBytes extends \RandomLib\AbstractSource
{
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return \is_callable('random_bytes');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* 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 (!self::isSupported()) {
return \str_repeat(chr(0), $size);
}
return \random_bytes($size);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*
* @link https://paragonie.com/book/pecl-libsodium
* @link http://pecl.php.net/package/libsodium
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class Sodium extends \RandomLib\AbstractSource
{
/**
* A property that may be forcibly set to `false` in the constructor, for
* the purpose of testing this source
*
* @var bool
*/
private $hasLibsodium = false;
/**
* Constructs a libsodium Random Number Source
*
* @param bool $useLibsodium May be set to `false` to disable libsodium for
* testing purposes
*/
public function __construct($useLibsodium = true)
{
if ($useLibsodium && extension_loaded('libsodium')) {
$this->hasLibsodium = true;
}
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return function_exists('Sodium\\randombytes_buf');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* 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 (!$this->hasLibsodium || $size < 1) {
return str_repeat(chr(0), $size);
}
return (string) \Sodium\randombytes_buf($size);
}
}

View File

@@ -0,0 +1,108 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class URandom extends \RandomLib\AbstractSource
{
/**
* @var string The file to read from
*/
protected static $file = '/dev/urandom';
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return (bool) @\file_exists(static::$file);
}
/**
* 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 ($size == 0) {
return static::emptyValue($size);
}
$file = \fopen(static::$file, 'rb');
if (!\is_resource($file)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
if (\is_callable('stream_set_read_buffer')) {
\stream_set_read_buffer($file, 0);
}
/** @var string $result */
$result = \fread($file, $size);
if (!\is_string($result)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
\fclose($file);
return $result;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class UniqID extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::LOW);
}
/**
* 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)
{
$result = '';
while (Util::safeStrlen($result) < $size) {
$result = uniqid($result, true);
}
return Util::safeSubstr($result, 0, $size);
}
}