31) { trigger_error(__d( 'cake_dev', 'Invalid value, cost must be between %s and %s', array(4, 31) ), E_USER_WARNING); return null; } self::$hashCost = $cost; } /** * Runs $text through a XOR cipher. * * *Note* This is not a cryptographically strong method and should not be used * for sensitive data. Additionally this method does *not* work in environments * where suhosin is enabled. * * Instead you should use Security::rijndael() when you need strong * encryption. * * @param string $text Encrypted string to decrypt, normal string to encrypt * @param string $key Key to use * @return string Encrypted/Decrypted string * @deprecated Will be removed in 3.0. */ public static function cipher($text, $key) { if (empty($key)) { trigger_error(__d('cake_dev', 'You cannot use an empty key for Security::cipher()'), E_USER_WARNING); return ''; } srand(Configure::read('Security.cipherSeed')); $out = ''; $keyLength = strlen($key); for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) { $j = ord(substr($key, $i % $keyLength, 1)); while ($j--) { rand(0, 255); } $mask = rand(0, 255); $out .= chr(ord(substr($text, $i, 1)) ^ $mask); } srand(); return $out; } /** * Encrypts/Decrypts a text using the given key using rijndael method. * * Prior to 2.3.1, a fixed initialization vector was used. This was not * secure. This method now uses a random iv, and will silently upgrade values when * they are re-encrypted. * * @param string $text Encrypted string to decrypt, normal string to encrypt * @param string $key Key to use as the encryption key for encrypted data. * @param string $operation Operation to perform, encrypt or decrypt * @return string Encrypted/Decrypted string */ public static function rijndael($text, $key, $operation) { if (empty($key)) { trigger_error(__d('cake_dev', 'You cannot use an empty key for Security::rijndael()'), E_USER_WARNING); return ''; } if (empty($operation) || !in_array($operation, array('encrypt', 'decrypt'))) { trigger_error(__d('cake_dev', 'You must specify the operation for Security::rijndael(), either encrypt or decrypt'), E_USER_WARNING); return ''; } if (strlen($key) < 32) { trigger_error(__d('cake_dev', 'You must use a key larger than 32 bytes for Security::rijndael()'), E_USER_WARNING); return ''; } $algorithm = MCRYPT_RIJNDAEL_256; $mode = MCRYPT_MODE_CBC; $ivSize = mcrypt_get_iv_size($algorithm, $mode); $cryptKey = substr($key, 0, 32); if ($operation === 'encrypt') { $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); return $iv . '$$' . mcrypt_encrypt($algorithm, $cryptKey, $text, $mode, $iv); } // Backwards compatible decrypt with fixed iv if (substr($text, $ivSize, 2) !== '$$') { $iv = substr($key, strlen($key) - 32, 32); return rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0"); } $iv = substr($text, 0, $ivSize); $text = substr($text, $ivSize + 2); return rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0"); } /** * 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 integer $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. */ protected static function _crypt($password, $salt = false) { if ($salt === false) { $salt = self::_salt(22); $salt = vsprintf('$2a$%02d$%s', array(self::$hashCost, $salt)); } if ($salt === true || strpos($salt, '$2a$') !== 0 || strlen($salt) < 29) { trigger_error(__d( 'cake_dev', 'Invalid salt: %s for %s Please visit http://www.php.net/crypt and read the appropriate section for building %s salts.', array($salt, 'blowfish', 'blowfish') ), E_USER_WARNING); return ''; } return crypt($password, $salt); } }