From 924909d5c2a2f80bd400967d65bcbac694bf6361 Mon Sep 17 00:00:00 2001 From: Enrico Zimuel Date: Wed, 23 Mar 2016 15:57:35 +0100 Subject: [PATCH 1/4] Removed the OpenSSL usage --- composer.json | 2 +- doc/book/zend.math.introduction.md | 25 +++++++++---------------- src/BigInteger/BigInteger.php | 2 +- src/Rand.php | 18 +++++++++--------- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/composer.json b/composer.json index 53106c5..cc6cf87 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "suggest": { "ext-bcmath": "If using the bcmath functionality", "ext-gmp": "If using the gmp functionality", - "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if OpenSSL/Mcrypt extensions are unavailable" + "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if Mcrypt extensions is unavailable" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/doc/book/zend.math.introduction.md b/doc/book/zend.math.introduction.md index 6a6a269..057d986 100644 --- a/doc/book/zend.math.introduction.md +++ b/doc/book/zend.math.introduction.md @@ -12,20 +12,13 @@ We expect to add more functionalities in the future. `Zend\Math\Rand` implements a random number generator that is able to generate random numbers for general purpose usage and for cryptographic scopes. To generate good random numbers this component -uses the [OpenSSL](http://php.net/manual/en/book.openssl.php) and the -[Mcrypt](http://it.php.net/manual/en/book.mcrypt.php) extension of PHP. If you don't have the -OpenSSL or the Mcrypt extension installed in your environment the component will use the -[mt\_rand](http://it.php.net/manual/en/function.mt-rand.php) function of PHP as fallback. The -`mt_rand` is not considered secure for cryptographic purpose, that means if you will try to use it -to generate secure random number the class will throw an exception. - -In particular, the algorithm that generates random bytes in `Zend\Math\Rand` tries to call the -[openssl\_random\_pseudo\_bytes](http://it.php.net/manual/en/function.openssl-random-pseudo-bytes.php) -function of the OpenSSL extension if installed. If the OpenSSL extension is not present in the -system the algorithm tries to use the the -[mcrypt\_create\_iv](http://it.php.net/manual/en/function.mcrypt-create-iv.php) function of the -Mcrypt extension (using the `MCRYPT_DEV_URANDOM` parameter). Finally, if the OpenSSL and Mcrypt are -not installed the generator uses the `mt_rand` function of PHP. +uses different approaches. If PHP 7 is running we used the cryptographically secure pseudo-random +functions [random_bytes](http://php.net/manual/en/function.random-bytes.php) and +[random_int](http://php.net/manual/en/function.random-int.php), otherwise we use the +[Mcrypt](http://it.php.net/manual/en/book.mcrypt.php) extension or /dev/urandom source with a mixer +function provided by . If you don't have a secure random source in your environment the component +will use the library [ircmaxell/RandomLib](https://github.com/ircmaxell/RandomLib) with a +medium strength generator. The `Zend\Math\Rand` class offers the following methods to generate random values: @@ -41,8 +34,8 @@ In all these methods the parameter `$strong` specify the usage of a strong rando We suggest to set the $strong to true if you need to generate random number for cryptographic and security implementation. -If `$strong` is set to true and you try to generate random values in a PHP environment without the -OpenSSL and the Mcrypt extensions the component will throw an Exception. +If `$strong` is set to true and you try to generate random values in a PHP environment without a +secure pseudo-random source the component will throw an Exception. Below we reported an example on how to generate random data using `Zend\Math\Rand`. diff --git a/src/BigInteger/BigInteger.php b/src/BigInteger/BigInteger.php index 97342be..37a13b0 100644 --- a/src/BigInteger/BigInteger.php +++ b/src/BigInteger/BigInteger.php @@ -78,7 +78,7 @@ public static function getAvailableAdapter() if (extension_loaded('gmp')) { return static::factory('Gmp'); } - + if (extension_loaded('bcmath')) { return static::factory('Bcmath'); } diff --git a/src/Rand.php b/src/Rand.php index 7a2095c..6b1c472 100644 --- a/src/Rand.php +++ b/src/Rand.php @@ -24,7 +24,8 @@ abstract class Rand protected static $generator = null; /** - * Generate random bytes using OpenSSL or Mcrypt and mt_rand() as fallback + * Generate random bytes using different approaches + * If PHP 7 is running we use the random_bytes() function * * @param int $length * @param bool $strong true if you need a strong random generator (cryptography) @@ -39,11 +40,8 @@ public static function getBytes($length, $strong = false) return false; } - if (function_exists('openssl_random_pseudo_bytes')) { - $bytes = openssl_random_pseudo_bytes($length, $usable); - if (true === $usable) { - return $bytes; - } + if (version_compare(PHP_VERSION, '7.0.0') >= 0) { + return random_bytes($length); } if (function_exists('mcrypt_create_iv')) { $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); @@ -56,7 +54,7 @@ public static function getBytes($length, $strong = false) if (true === $strong && false === $checkAlternatives) { throw new Exception\RuntimeException( 'This PHP environment doesn\'t support secure random number generation. ' . - 'Please consider installing the OpenSSL and/or Mcrypt extensions' + 'Please consider installing Mcrypt extension or use PHP 7' ); } $generator = self::getAlternativeGenerator(); @@ -76,8 +74,7 @@ public static function getAlternativeGenerator() if (!class_exists('RandomLib\\Factory')) { throw new Exception\RuntimeException( 'The RandomLib fallback pseudorandom number generator (PRNG) ' - . ' must be installed in the absence of the OpenSSL and ' - . 'Mcrypt extensions' + . ' must be installed in the absence of a secure source' ); } $factory = new RandomLib\Factory; @@ -117,6 +114,9 @@ public static function getInteger($min, $max, $strong = false) 'The min parameter must be lower than max parameter' ); } + if (version_compare(PHP_VERSION, '7.0.0') >= 0) { + return random_int($min, $max); + } $range = $max - $min; if ($range == 0) { return $max; From e229c3fdbed0840fb9108ef6d3aff9d8bf7e14c7 Mon Sep 17 00:00:00 2001 From: Enrico Zimuel Date: Wed, 23 Mar 2016 17:07:17 +0100 Subject: [PATCH 2/4] Usage of function_exists() + fix doc --- doc/book/zend.math.introduction.md | 4 ++-- src/Rand.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/book/zend.math.introduction.md b/doc/book/zend.math.introduction.md index 057d986..3aa53b2 100644 --- a/doc/book/zend.math.introduction.md +++ b/doc/book/zend.math.introduction.md @@ -15,8 +15,8 @@ general purpose usage and for cryptographic scopes. To generate good random numb uses different approaches. If PHP 7 is running we used the cryptographically secure pseudo-random functions [random_bytes](http://php.net/manual/en/function.random-bytes.php) and [random_int](http://php.net/manual/en/function.random-int.php), otherwise we use the -[Mcrypt](http://it.php.net/manual/en/book.mcrypt.php) extension or /dev/urandom source with a mixer -function provided by . If you don't have a secure random source in your environment the component +[Mcrypt](http://it.php.net/manual/en/book.mcrypt.php) extension or /dev/urandom source. +If you don't have a secure random source in your environment the component will use the library [ircmaxell/RandomLib](https://github.com/ircmaxell/RandomLib) with a medium strength generator. diff --git a/src/Rand.php b/src/Rand.php index 6b1c472..e36ebd2 100644 --- a/src/Rand.php +++ b/src/Rand.php @@ -40,7 +40,7 @@ public static function getBytes($length, $strong = false) return false; } - if (version_compare(PHP_VERSION, '7.0.0') >= 0) { + if (function_exists('random_bytes')) { // available in PHP 7 return random_bytes($length); } if (function_exists('mcrypt_create_iv')) { @@ -114,7 +114,7 @@ public static function getInteger($min, $max, $strong = false) 'The min parameter must be lower than max parameter' ); } - if (version_compare(PHP_VERSION, '7.0.0') >= 0) { + if (function_exists('random_int')) { // available in PHP 7 return random_int($min, $max); } $range = $max - $min; From 9fbd17070776c4d4dcd3d73e468000a12d8f798c Mon Sep 17 00:00:00 2001 From: Enrico Zimuel Date: Thu, 7 Apr 2016 16:07:21 +0200 Subject: [PATCH 3/4] Fixed the Exception messages --- src/Rand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Rand.php b/src/Rand.php index e36ebd2..6e8068a 100644 --- a/src/Rand.php +++ b/src/Rand.php @@ -54,7 +54,7 @@ public static function getBytes($length, $strong = false) if (true === $strong && false === $checkAlternatives) { throw new Exception\RuntimeException( 'This PHP environment doesn\'t support secure random number generation. ' . - 'Please consider installing Mcrypt extension or use PHP 7' + 'Please consider either installing ext/mcrypt or upgrading to PHP 7' ); } $generator = self::getAlternativeGenerator(); @@ -73,8 +73,8 @@ public static function getAlternativeGenerator() } if (!class_exists('RandomLib\\Factory')) { throw new Exception\RuntimeException( - 'The RandomLib fallback pseudorandom number generator (PRNG) ' - . ' must be installed in the absence of a secure source' + 'The RandomLib fallback pseudorandom generator is not installed. '. + 'Please install it to support secure random numbers' ); } $factory = new RandomLib\Factory; From 3e7121dcc0ba990930dbde99d73654383126adc0 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 7 Apr 2016 09:29:30 -0500 Subject: [PATCH 4/4] Added CHANGELOG for #16 - What you did --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33ce966..c50937e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,11 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#16](https://github.com/zendframework/zend-math/pull/16) updates + `Zend\Math\Rand` to use PHP 7's `random_bytes()` and `random_int()` when + detected, and fallback to `ircmaxell/RandomLib` otherwise, instead of using + either mcrypt or openssl. This provides more cryptographically secure + pseudo-random generation. ## 2.6.1 - TBD