cipher = $cipher; $this->mode = $mode; $this->rounds = (int)$rounds; } /** * Decrypt the data with the provided key * * @param string $data The encrypted datat to decrypt * @param string $key The key to use for decryption * * @returns string|false The returned string if decryption is successful * false if it is not */ // public function decrypt($data, $key) // { // $salt = substr($data, 0, 128); // $enc = substr($data, 128, -64); // $mac = substr($data, -64); // list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key); // if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) { // return false; // } // $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv); // $data = $this->unpad($dec); // return $data; // } /** * Encrypt the supplied data using the supplied key * * @param string $data The data to encrypt * @param string $key The key to encrypt with * * @returns string The encrypted data */ // public function encrypt($data, $key) // { // $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM); // list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key); // $data = $this->pad($data); // $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv); // $mac = hash_hmac('sha512', $enc, $macKey, true); // return $salt . $enc . $mac; // } /** * Generates a set of keys given a random salt and a master key * * @param string $salt A random string to change the keys each encryption * @param string $key The supplied key to encrypt with * * @returns array An array of keys (a cipher key, a mac key, and a IV) */ protected function getKeys($salt, $key) { // $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode); // $keySize = mcrypt_get_key_size($this->cipher, $this->mode); $length = 2 * $keySize + $ivSize; $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length); $cipherKey = substr($key, 0, $keySize); $macKey = substr($key, $keySize, $keySize); $iv = substr($key, 2 * $keySize); return array($cipherKey, $macKey, $iv); } /** * Stretch the key using the PBKDF2 algorithm * * @see http://en.wikipedia.org/wiki/PBKDF2 * * @param string $algo The algorithm to use * @param string $key The key to stretch * @param string $salt A random salt * @param int $rounds The number of rounds to derive * @param int $length The length of the output key * * @returns string The derived key. */ protected function pbkdf2($algo, $key, $salt, $rounds, $length) { $size = strlen(hash($algo, '', true)); $len = ceil($length / $size); $result = ''; for ($i = 1; $i <= $len; $i++) { $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true); $res = $tmp; for ($j = 1; $j < $rounds; $j++) { $tmp = hash_hmac($algo, $tmp, $key, true); $res ^= $tmp; } $result .= $res; } return substr($result, 0, $length); } /** * @param $data * @return string */ protected function pad($data) { // $length = mcrypt_get_block_size($this->cipher, $this->mode); $padAmount = $length - strlen($data) % $length; if ($padAmount == 0) { $padAmount = $length; } return $data . str_repeat(chr($padAmount), $padAmount); } /** * @param $data * @return bool|string */ protected function unpad($data) { // $length = mcrypt_get_block_size($this->cipher, $this->mode); $last = ord($data[strlen($data) - 1]); if ($last > $length) return false; if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) { return false; } return substr($data, 0, -1 * $last); } /** * @param $a * @param $b * @return bool */ function hash_equals($a, $b) { // $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM); return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key); } }