diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 1ed1c0eb1..31a61f20d 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -534,7 +534,7 @@ class SecurityComponent extends Component { } return false; } - $authKey = Security::generateAuthKey(); + $authKey = hash('sha512', Security::randomBytes(16), false); $token = array( 'key' => $authKey, 'allowedControllers' => $this->allowedControllers, diff --git a/lib/Cake/Test/Case/Cache/Engine/MemcachedEngineTest.php b/lib/Cake/Test/Case/Cache/Engine/MemcachedEngineTest.php index 2e915c4ef..babdf9779 100644 --- a/lib/Cake/Test/Case/Cache/Engine/MemcachedEngineTest.php +++ b/lib/Cake/Test/Case/Cache/Engine/MemcachedEngineTest.php @@ -346,6 +346,7 @@ class MemcachedEngineTest extends CakeTestCase { * @return void */ public function testSaslAuthException() { + $this->skipIf(version_compare(PHP_VERSION, '7.0.0', '>=')); $Memcached = new TestMemcachedEngine(); $settings = array( 'engine' => 'Memcached', diff --git a/lib/Cake/Test/Case/Utility/SecurityTest.php b/lib/Cake/Test/Case/Utility/SecurityTest.php index 90ea96c86..18378725a 100644 --- a/lib/Cake/Test/Case/Utility/SecurityTest.php +++ b/lib/Cake/Test/Case/Utility/SecurityTest.php @@ -424,4 +424,16 @@ class SecurityTest extends CakeTestCase { Security::decrypt($txt, $key); } +/** + * Test the random method. + * + * @return void + */ + public function testRandomBytes() { + $value = Security::randomBytes(16); + $this->assertSame(16, strlen($value)); + + $value = Security::randomBytes(64); + $this->assertSame(64, strlen($value)); + } } diff --git a/lib/Cake/Utility/Security.php b/lib/Cake/Utility/Security.php index 511cf5efc..d7fcb00eb 100644 --- a/lib/Cake/Utility/Security.php +++ b/lib/Cake/Utility/Security.php @@ -61,6 +61,7 @@ class Security { * Generate authorization hash. * * @return string Hash + * @deprecated 2.8.1 This method was removed in 3.0.0 */ public static function generateAuthKey() { return Security::hash(CakeText::uuid()); @@ -71,6 +72,7 @@ class Security { * * @param string $authKey Authorization hash * @return bool Success + * @deprecated 2.8.1 This method was removed in 3.0.0 */ public static function validateAuthKey($authKey) { return true; @@ -92,7 +94,7 @@ class Security { * Creating a blowfish/bcrypt hash: * * ``` - * $hash = Security::hash($password, 'blowfish'); + * $hash = Security::hash($password, 'blowfish'); * ``` * * @param string $string String to hash @@ -166,6 +168,35 @@ class Security { static::$hashCost = $cost; } +/** + * Get random bytes from a secure source. + * + * This method will fall back to an insecure source an trigger a warning + * if it cannot find a secure source of random data. + * + * @param int $length The number of bytes you want. + * @return string Random bytes in binary. + */ + public static function randomBytes($length) { + if (function_exists('random_bytes')) { + return random_bytes($length); + } + if (function_exists('openssl_random_pseudo_bytes')) { + return openssl_random_pseudo_bytes($length); + } + trigger_error( + 'You do not have a safe source of random data available. ' . + 'Install either the openssl extension, or paragonie/random_compat. ' . + 'Falling back to an insecure random source.', + E_USER_WARNING + ); + $bytes = ''; + while ($bytes < $length) { + $bytes .= static::hash(CakeText::uuid() . uniqid(mt_rand(), true), 'sha512', true); + } + return substr($bytes, 0, $length); + } + /** * Runs $text through a XOR cipher. *