mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-16 18:25:13 +00:00
Random: include the Crypt_* classes if they're available
also error out if none are available
This commit is contained in:
parent
90bc07e292
commit
638e6c78ec
@ -120,7 +120,7 @@ if (!function_exists('crypt_random_string')) {
|
|||||||
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
|
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
|
||||||
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
|
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
|
||||||
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
|
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
|
||||||
// however. a ton of people visiting the website. obviously you don't want to base your seeding
|
// however, a ton of people visiting the website. obviously you don't want to base your seeding
|
||||||
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
|
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
|
||||||
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
|
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
|
||||||
// on the data sent by all users. one user requests the page and a hash of their info is saved.
|
// on the data sent by all users. one user requests the page and a hash of their info is saved.
|
||||||
@ -191,21 +191,45 @@ if (!function_exists('crypt_random_string')) {
|
|||||||
//
|
//
|
||||||
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
|
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case class_exists('Crypt_AES'):
|
case stream_resolve_include_path('Crypt/AES.php'):
|
||||||
|
if (!class_exists('Crypt_AES')) {
|
||||||
|
include_once 'AES.php';
|
||||||
|
}
|
||||||
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
||||||
break;
|
break;
|
||||||
case class_exists('Crypt_TripleDES'):
|
case stream_resolve_include_path('Crypt/Twofish.php'):
|
||||||
|
if (!class_exists('Crypt_Twofish')) {
|
||||||
|
include_once 'Twofish.php';
|
||||||
|
}
|
||||||
|
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
|
||||||
|
break;
|
||||||
|
case stream_resolve_include_path('Crypt/Blowfish.php'):
|
||||||
|
if (!class_exists('Crypt_Blowfish')) {
|
||||||
|
include_once 'Blowfish.php';
|
||||||
|
}
|
||||||
|
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
|
||||||
|
break;
|
||||||
|
case stream_resolve_include_path('Crypt/TripleDES.php'):
|
||||||
|
if (!class_exists('Crypt_TripleDES')) {
|
||||||
|
include_once 'TripleDES.php';
|
||||||
|
}
|
||||||
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
||||||
break;
|
break;
|
||||||
case class_exists('Crypt_DES'):
|
case stream_resolve_include_path('Crypt/DES.php'):
|
||||||
|
if (!class_exists('Crypt_DES')) {
|
||||||
|
include_once 'DES.php';
|
||||||
|
}
|
||||||
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
||||||
break;
|
break;
|
||||||
case class_exists('Crypt_RC4'):
|
case stream_resolve_include_path('Crypt/RC4.php'):
|
||||||
|
if (!class_exists('Crypt_RC4')) {
|
||||||
|
include_once 'RC4.php';
|
||||||
|
}
|
||||||
$crypto = new Crypt_RC4();
|
$crypto = new Crypt_RC4();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$crypto = $seed;
|
user_error('crypt_random_string requires at least one symmetric cipher be loaded');
|
||||||
return crypt_random_string($length);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$crypto->setKey($key);
|
$crypto->setKey($key);
|
||||||
@ -213,39 +237,51 @@ if (!function_exists('crypt_random_string')) {
|
|||||||
$crypto->enableContinuousBuffer();
|
$crypto->enableContinuousBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($crypto)) {
|
|
||||||
// the following is based off of ANSI X9.31:
|
|
||||||
//
|
|
||||||
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
|
|
||||||
//
|
|
||||||
// OpenSSL uses that same standard for it's random numbers:
|
|
||||||
//
|
|
||||||
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
|
|
||||||
// (do a search for "ANS X9.31 A.2.4")
|
|
||||||
//
|
|
||||||
// ANSI X9.31 recommends ciphers be used and phpseclib does use them if they're available (see
|
|
||||||
// later on in the code) but if they're not we'll use sha1
|
|
||||||
$result = '';
|
|
||||||
while (strlen($result) < $length) { // each loop adds 20 bytes
|
|
||||||
// microtime() isn't packed as "densely" as it could be but then neither is that the idea.
|
|
||||||
// the idea is simply to ensure that each "block" has a unique element to it.
|
|
||||||
$i = pack('H*', sha1(microtime()));
|
|
||||||
$r = pack('H*', sha1($i ^ $v));
|
|
||||||
$v = pack('H*', sha1($r ^ $i));
|
|
||||||
$result.= $r;
|
|
||||||
}
|
|
||||||
return substr($result, 0, $length);
|
|
||||||
}
|
|
||||||
|
|
||||||
//return $crypto->encrypt(str_repeat("\0", $length));
|
//return $crypto->encrypt(str_repeat("\0", $length));
|
||||||
|
|
||||||
|
// the following is based off of ANSI X9.31:
|
||||||
|
//
|
||||||
|
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
|
||||||
|
//
|
||||||
|
// OpenSSL uses that same standard for it's random numbers:
|
||||||
|
//
|
||||||
|
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
|
||||||
|
// (do a search for "ANS X9.31 A.2.4")
|
||||||
$result = '';
|
$result = '';
|
||||||
while (strlen($result) < $length) {
|
while (strlen($result) < $length) {
|
||||||
$i = $crypto->encrypt(microtime());
|
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
|
||||||
$r = $crypto->encrypt($i ^ $v);
|
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
|
||||||
$v = $crypto->encrypt($r ^ $i);
|
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
|
||||||
$result.= $r;
|
$result.= $r;
|
||||||
}
|
}
|
||||||
return substr($result, 0, $length);
|
return substr($result, 0, $length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('stream_resolve_include_path')) {
|
||||||
|
/**
|
||||||
|
* Resolve filename against the include path.
|
||||||
|
*
|
||||||
|
* stream_resolve_include_path was introduced in PHP 5.3.2. This is kinda a PHP_Compat layer for those not using that version.
|
||||||
|
*
|
||||||
|
* @param Integer $length
|
||||||
|
* @return String
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function stream_resolve_include_path($filename)
|
||||||
|
{
|
||||||
|
$paths = PATH_SEPARATOR == ':' ?
|
||||||
|
preg_split('#(?<!phar):#', get_include_path()) :
|
||||||
|
explode(PATH_SEPARATOR, get_include_path());
|
||||||
|
foreach ($paths as $prefix) {
|
||||||
|
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
|
||||||
|
$file = $prefix . $ds . $filename;
|
||||||
|
|
||||||
|
if (file_exists($file)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user