/ Published in: PHP
HMAC cookie implementation based on BigOrNot_CookieManager by Mattieu Huguet. (http://bigornot.blogspot.com/2008/06/securing-cookies-php-implementation.html) Rewritten for clarity, updated for use with PHP 5 and Zend Framework dependencies removed by Mark A. LaDoux.
Expand |
Embed | Plain Text
<?php /****************************************************************************** Cookie Class HMAC cookie implementation based on BigOrNot_CookieManager by Mattieu Huguet. (http://bigornot.blogspot.com/2008/06/securing-cookies-php-implementation.html) Rewritten for clarity and updated for use with PHP 5 by Mark A. LaDoux. /******************************************************************************/ class Cookie { /************************************************************************** Settings /**************************************************************************/ // used to encrypt cookie // data // ( whether or not our // cookie data is // encrypted. ) /************************************************************************** Constructor @access public @param array $config Settings for the cookie class @return null Function does not return a result /**************************************************************************/ public function __construct($config = null) { // Check config format // REQUIRED SETTING self::$key = $config['key']; // OPTIONAL SETTINGS // Load mcrypt module self::$cmod = mcrypt_module_open(self::$calg, '', self::$mode, ''); if(self::$cmod === false) } /************************************************************************** Get High Confidentiality Mode Reports whether High Confidentiality Mode is enabled or disabled. @access public @return bool TRUE if enabled, FALSE if not /**************************************************************************/ public function get_hi_c() { return self::$hi_c; } /************************************************************************** Set High Confidentiality Mode ( Enabled by default ) Turns cookie data encryption on and off @access public @param bool $enable TRUE to enable, FALSE to disable @return mixed returns self instance /**************************************************************************/ public function set_hi_c($enable) { // if format is invalid, do nothing and return instance // set value self::$hi_c = $enable; // return instance return self; } /************************************************************************** Get SSL Suport Reports whether or not SSL is enabled or disabled @access public @return bool TRUE if enabled, FALSE if disabled /**************************************************************************/ public function get_ssl() { return self::$ssl; } /************************************************************************** Set SSL Support ( Disabled by default ) Turns SSL support on or off. @access public @param bool $enable TRUE to enable, FALSE to disable @return mixed Returns self instance /**************************************************************************/ public function set_ssl($enable) { // if format is invalid, do nothing and return instance // set value self::$ssl = $enable; // return instance return self; } /************************************************************************** Set a secure cookie @access public @param string $name name of cookie @param string $value cookie data @param string $cid cookie ID @param int $expire cookie TTL @param string $path cookie path @param string $domain cookie domain @param bool $secure when TRUE, cookie requires an SSL connection @param bool $httponly when TRUE, cookie is only accessable through HTTP protocol @return null function does not return a result /**************************************************************************/ public function set_cookie( $name, $value, $cid, $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = true ) { // secure cookie value $secure_value = $this->secure_cookie_value($value, $cid, $expire); // set the cookie $this->set_classic_cookie( $name, $secure_value, $expire, $path, $domain, $secure, $httponly ); } /************************************************************************** Delete a cookie @access public @param string $name name of cookie @param string $path cookie path @param string $domain cookie domain @param bool $secure When TRUE, cookies require an SSL connection @param bool $httponly When TRUE, cookie is only accessable through HTTP protocol @return null function does not return a result /**************************************************************************/ public function delete_cookie( $name, $path = '/', $domain = '', $secure = false, $httponly = true ) { // set expiration to 1980-01-01 $expire = 315554400; // set cookie $this->set_classic_cookie( $name, '', $expire, $path, $domain, $secure, $httponly ); } /************************************************************************** Get secure cookie value Verifies the integrity of the cookie data and decrypts it. If cookie is invalid, it can be automatically destroyed (default). @access public @param string $name name of cookie @param string $del_invalid destroy invalid cookies @return mixed if valid, returns array, otherwise false /**************************************************************************/ public function get_cookie_value($name, $del_invalid = true) { // check if cookie exists if(! $this->cookie_exists($name)) return false; // get cookie data { // prepare cookie data $key = hash_hmac(self::$halg, $values[0].$values[1], self::$key); if($this->get_hi_c()) { } else { $data = $cookie_data; } // verify data { $verify_key = hash_hmac( self::$halg, $values[0].$values[1].$data.$_SERVER['SSL_SESSION_ID'], $key ); } else { $verify_key = hash_hmac( self::$halg, $values[0].$values[1].$data, $key ); } if($verify_key == $values[3]) return $data; } // Delete invalid cookies if($del_invalid) $this->delete_cookie($name); // return false return false; } /************************************************************************** Set a classic cookie ( unsecure ) @access public @param string $name cookie name @param string $value cookie value @param int $expire cookie TTL @param string $path cookie path @param string $domain cookie domain @param bool $secure when TRUE, requires SSL connection @param bool $httponly when true, cookie only available over HTTP protocol @return null function does not return anything /**************************************************************************/ function set_classic_cookie( $name, $value, $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = true ) { // DEPRECIATED: for use with PHP < 5.2 $name, $value, $expire, $path, $domain, $secure ); $name, $value, $expire, $path, $domain, $httponly ); } /************************************************************************** Check if cookie exists @access public @param $name name of cookie to check @return bool TRUE if exists, FALSE if doesn't /**************************************************************************/ public function cookie_exists($name) { } /************************************************************************** Secure Cookie Value the initial value is transformed with this protocol : secure_value = cid|expire|base64((value)k,expire)|HMAC(cid|expire|value,k) where k = HMAC(cid|expire, sk) and sk is server's secret key. (value)k,md5(expire) is the result of a cryptographic function ( ie: AES256 ) on "value" with key k and initialization vector md5(expire). @access protected @param string $value insecure value @param string $cid cookie id @param int $expire data TTL @return string secured value /**************************************************************************/ protected function secure_cookie_value($value, $cid, $expire) { // generate key $key = hash_hmac(self::$halg, $cid.$expire, self::$key); // encrypt data if($this->get_hi_c()) { $value, $key, )); } else { } // generate verification key { $verify_key = hash_hmac( self::$halg, $cid.$expire.$value.$_SERVER['SSL_SESSION_ID'], $key ); } else { $verify_key = hash_hmac( self::$halg, $cid.$expire.$value, $key ); } // prepare data } /************************************************************************** Encrypt a given data with a given key and a given initialization vector @access protected @param string $data data to encrypt @param string $key secret key @param string $iv initialisation vector @return string encrypted data /**************************************************************************/ protected function encrypt($data, $key, $iv) { // prepare the initialization vectore $iv = $this->validate_iv($iv); // prepare the secret key $key = $this->validate_key($key); // encrypt data mcrypt_generic_init(self::$cmod, $key, $iv); $res = mcrypt_generic(self::$cmod, $data); mcrypt_generic_deinit(self::$cmod); // return encrypted data return $res; } /************************************************************************** Decrypt a given data with a given key and a given initialization vector @access protected @param string $data data to decrypt @param string $key secret key @param string $iv initialization vector @return string decrypted data /**************************************************************************/ protected function decrypt($data, $key, $iv) { // prepare the initialization vector $iv = $this->validate_iv($iv); // prepare the secret key $key = $this->validate_key($key); // decrypt data mcrypt_generic_init(self::$cmod, $key, $iv); $decrypted_data = mdecrypt_generic(self::$cmod, $data); mcrypt_generic_deinit(self::$cmod); // return decrypted data return $res; } /************************************************************************** Validate initialization vector If the given IV is too long for the selected mcrypt algorithm, it will be truncated. @access protected @param string $iv Initialization vector @return string truncated initialization vector /**************************************************************************/ protected function validate_iv($iv) { // get IV size $iv_size = mcrypt_enc_get_iv_size(self::$cmod); // truncate IV // return truncated IV return $iv; } /************************************************************************** Validate key If the given secret key is too long for the selected mcrypt algorithm, it will be truncated. @access protected @param string $key Secret key @return string Truncated secret key /**************************************************************************/ protected function validate_key($key) { // get key size $key_size = mcrypt_enc_get_key_size(self::$cmod); // truncate key // return truncated key return $key; } }
You need to login to post a comment.
