Browse Source

Remove blowfish hash generation support from Security::hash().

You should use password_hash() / password_verify() instead.
ADmad 11 years ago
parent
commit
2b2fa9792f

+ 6 - 92
src/Utility/Security.php

@@ -24,20 +24,14 @@ use Cake\Error\Exception;
 class Security {
 
 /**
- * Default hash method. Default to 'sha1'.
+ * Default hash method. If `$type` param for `Security::hash()` is not specified
+ * this value is used. Defaults to 'sha1'.
  *
  * @var string
  */
 	public static $hashType = 'sha1';
 
 /**
- * Default cost
- *
- * @var string
- */
-	public static $hashCost = '10';
-
-/**
  * Generate authorization hash.
  *
  * @return string Hash
@@ -49,27 +43,12 @@ class Security {
 /**
  * Create a hash from string using given method.
  *
- * #### Using Blowfish
- *
- * - Creating Hashes: *Do not supply a salt*. CakePHP handles salt creation for
- *   you ensuring that each hashed password will have a *unique* salt.
- * - Comparing Hashes: Simply pass the originally hashed password as the salt.
- *   The salt is prepended to the hash and php handles the parsing automagically.
- * - Do NOT use a constant salt for blowfish!
- *
- * Creating a blowfish/bcrypt hash:
- *
- * {{{
- * 	$hash = Security::hash($password, 'blowfish');
- * }}}
- *
  * @param string $string String to hash
- * @param string $type Hashing algo to use (i.e. sha1, sha256, blowfish etc.).
- *   Can be any valid algo included in list returned by hash_algos() or 'blowfish'.
+ * @param string $type Hashing algo to use (i.e. sha1, sha256 etc.).
+ *   Can be any valid algo included in list returned by hash_algos().
  *   If no value is passed the type specified by `Security::$hashType` is used.
  * @param mixed $salt If true, automatically prepends the application's salt
- *   value to $string (Security.salt). If you are using blowfish the salt
- *   must be false or a previously generated salt.
+ *   value to $string (Security.salt).
  * @return string Hash
  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/security.html#Security::hash
  */
@@ -79,9 +58,6 @@ class Security {
 		}
 		$type = strtolower($type);
 
-		if ($type === 'blowfish') {
-			return static::_crypt($string, $salt);
-		}
 		if ($salt) {
 			if (!is_string($salt)) {
 				$salt = Configure::read('Security.salt');
@@ -96,7 +72,7 @@ class Security {
  * Sets the default hash method for the Security object. This affects all objects
  * using Security::hash().
  *
- * @param string $hash Method to use (sha1/sha256/md5/blowfish etc.)
+ * @param string $hash Method to use (sha1/sha256/md5 etc.)
  * @return void
  * @see Security::hash()
  */
@@ -105,23 +81,6 @@ class Security {
 	}
 
 /**
- * Sets the cost for they blowfish hash method.
- *
- * @param int $cost Valid values are 4-31
- * @return void
- * @throws \Cake\Error\Exception When cost is invalid.
- */
-	public static function setCost($cost) {
-		if ($cost < 4 || $cost > 31) {
-			throw new Exception(vsprintf(
-				'Invalid value, cost must be between %s and %s',
-				array(4, 31)
-			));
-		}
-		static::$hashCost = $cost;
-	}
-
-/**
  * Encrypts/Decrypts a text using the given key using rijndael method.
  *
  * @param string $text Encrypted string to decrypt, normal string to encrypt
@@ -156,51 +115,6 @@ class Security {
 	}
 
 /**
- * Generates a pseudo random salt suitable for use with php's crypt() function.
- * The salt length should not exceed 27. The salt will be composed of
- * [./0-9A-Za-z]{$length}.
- *
- * @param int $length The length of the returned salt
- * @return string The generated salt
- */
-	protected static function _salt($length = 22) {
-		$salt = str_replace(
-			array('+', '='),
-			'.',
-			base64_encode(sha1(uniqid(Configure::read('Security.salt'), true), true))
-		);
-		return substr($salt, 0, $length);
-	}
-
-/**
- * One way encryption using php's crypt() function. To use blowfish hashing see ``Security::hash()``
- *
- * @param string $password The string to be encrypted.
- * @param mixed $salt false to generate a new salt or an existing salt.
- * @return string The hashed string or an empty string on error.
- * @throws \Cake\Error\Exception on invalid salt values.
- */
-	protected static function _crypt($password, $salt = false) {
-		if ($salt === false) {
-			$salt = static::_salt(22);
-			$salt = vsprintf('$2y$%02d$%s', array(static::$hashCost, $salt));
-		}
-
-		$invalidCipher = (
-			strpos($salt, '$2y$') !== 0 &&
-			strpos($salt, '$2x$') !== 0 &&
-			strpos($salt, '$2a$') !== 0
-		);
-		if ($salt === true || $invalidCipher || strlen($salt) < 29) {
-			throw new Exception(sprintf(
-				'Invalid salt: %s for blowfish Please visit http://www.php.net/crypt and read the appropriate section for building blowfish salts.',
-				$salt
-			));
-		}
-		return crypt($password, $salt);
-	}
-
-/**
  * Encrypt a value using AES-256.
  *
  * *Caveat* You cannot properly encrypt/decrypt data with trailing null bytes.

+ 1 - 3
tests/TestCase/Auth/BasicAuthenticateTest.php

@@ -1,7 +1,5 @@
 <?php
 /**
- * BasicAuthenticateTest file
- *
  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  *
@@ -52,7 +50,7 @@ class BasicAuthenticateTest extends TestCase {
 			'realm' => 'localhost'
 		));
 
-		$password = Security::hash('password', 'blowfish', false);
+		$password = password_hash('password', PASSWORD_BCRYPT);
 		$User = TableRegistry::get('Users');
 		$User->updateAll(['password' => $password], []);
 		$this->response = $this->getMock('Cake\Network\Response');

+ 1 - 3
tests/TestCase/Auth/FormAuthenticateTest.php

@@ -1,7 +1,5 @@
 <?php
 /**
- * FormAuthenticateTest file
- *
  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  *
@@ -234,7 +232,7 @@ class FormAuthenticateTest extends TestCase {
 		$PluginModel = TableRegistry::get('TestPlugin.AuthUsers');
 		$user['id'] = 1;
 		$user['username'] = 'gwoo';
-		$user['password'] = Security::hash(Configure::read('Security.salt') . 'cake', 'blowfish', false);
+		$user['password'] = password_hash(Configure::read('Security.salt') . 'cake', PASSWORD_BCRYPT);
 		$PluginModel->save(new Entity($user));
 
 		$this->auth->config('userModel', 'TestPlugin.AuthUsers');

+ 1 - 1
tests/TestCase/Controller/Component/AuthComponentTest.php

@@ -76,7 +76,7 @@ class AuthComponentTest extends TestCase {
 		$this->Auth = new TestAuthComponent($this->Controller->components());
 
 		$Users = TableRegistry::get('AuthUsers');
-		$Users->updateAll(['password' => Security::hash('cake', 'blowfish', false)], []);
+		$Users->updateAll(['password' => password_hash('cake', PASSWORD_BCRYPT)], []);
 	}
 
 /**

+ 0 - 82
tests/TestCase/Utility/SecurityTest.php

@@ -34,45 +34,6 @@ class SecurityTest extends TestCase {
 	}
 
 /**
- * testHashInvalidSalt method
- *
- * @expectedException \Cake\Error\Exception
- * @return void
- */
-	public function testHashInvalidSalt() {
-		Security::hash('someKey', 'blowfish', true);
-	}
-
-/**
- * testHashAnotherInvalidSalt
- *
- * @expectedException \Cake\Error\Exception
- * @return void
- */
-	public function testHashAnotherInvalidSalt() {
-		Security::hash('someKey', 'blowfish', '$1$lksdjoijfaoijs');
-	}
-
-/**
- * testHashYetAnotherInvalidSalt
- *
- * @expectedException \Cake\Error\Exception
- * @return void
- */
-	public function testHashYetAnotherInvalidSalt() {
-		Security::hash('someKey', 'blowfish', '$2a$10$123');
-	}
-
-/**
- * testHashInvalidCost method
- *
- * @expectedException \Cake\Error\Exception
- * @return void
- */
-	public function testHashInvalidCost() {
-		Security::setCost(1000);
-	}
-/**
  * testHash method
  *
  * @return void
@@ -116,49 +77,6 @@ class SecurityTest extends TestCase {
 	}
 
 /**
- * Test that hash() works with blowfish.
- *
- * @return void
- */
-	public function testHashBlowfish() {
-		Security::setCost(10);
-		$test = Security::hash('password', 'blowfish');
-
-		$_hashType = Security::$hashType;
-
-		$key = 'someKey';
-		$hashType = 'blowfish';
-		Security::setHash($hashType);
-
-		$this->assertSame($hashType, Security::$hashType);
-		$this->assertSame(60, strlen(Security::hash($key, null, false)));
-
-		$password = $submittedPassword = $key;
-		$storedPassword = Security::hash($password);
-
-		$hashedPassword = Security::hash($submittedPassword, null, $storedPassword);
-		$this->assertSame($storedPassword, $hashedPassword);
-
-		$submittedPassword = 'someOtherKey';
-		$hashedPassword = Security::hash($submittedPassword, null, $storedPassword);
-		$this->assertNotSame($storedPassword, $hashedPassword);
-
-		$expected = sha1('customsaltsomevalue');
-		$result = Security::hash('somevalue', 'sha1', 'customsalt');
-		$this->assertSame($expected, $result);
-
-		$oldSalt = Configure::read('Security.salt');
-		Configure::write('Security.salt', 'customsalt');
-
-		$expected = sha1('customsaltsomevalue');
-		$result = Security::hash('somevalue', 'sha1', true);
-		$this->assertSame($expected, $result);
-
-		Configure::write('Security.salt', $oldSalt);
-		Security::setHash($_hashType);
-	}
-
-/**
  * testRijndael method
  *
  * @return void