I would like to save data in cookies (user name, email address, etc...) but I don't the user to easily read it or modify it. I need to be able able to read the data back. How can I do that with php 5.2+?
It would be used for "welcome back bob" kind of feature. It is not a replacement for persistence or session storage.
We use mcrypt in our projects to achieve encryption. Below is a code sample based on content found on the internet:
<?php
class MyProjCrypt {
private $td;
private $iv;
private $ks;
private $salt;
private $encStr;
private $decStr;
/**
* The constructor initializes the cryptography library
* @param $salt string The encryption key
* @return void
*/
function __construct($salt) {
$this->td = mcrypt_module_open('rijndael-256', '', 'ofb', ''); // algorithm
$this->ks = mcrypt_enc_get_key_size($this->td); // key size needed for the algorithm
$this->salt = substr(md5($salt), 0, $this->ks);
}
/**
* Generates a hex string of $src
* @param $src string String to be encrypted
* @return void
*/
function encrypt($src) {
srand(( double) microtime() * 1000000); //for sake of MCRYPT_RAND
$this->iv = mcrypt_create_iv($this->ks, MCRYPT_RAND);
mcrypt_generic_init($this->td, $this->salt, $this->iv);
$tmpStr = mcrypt_generic($this->td, $src);
mcrypt_generic_deinit($this->td);
mcrypt_module_close($this->td);
//convert the encrypted binary string to hex
//$this->iv is needed to decrypt the string later. It has a fixed length and can easily
//be seperated out from the encrypted String
$this->encStr = bin2hex($this->iv.$tmpStr);
}
/**
* Decrypts a hex string
* @param $src string String to be decrypted
* @return void
*/
function decrypt($src) {
//convert the hex string to binary
$corrected = preg_replace("[^0-9a-fA-F]", "", $src);
$binenc = pack("H".strlen($corrected), $corrected);
//retrieve the iv from the encrypted string
$this->iv = substr($binenc, 0, $this->ks);
//retrieve the encrypted string alone(minus iv)
$binstr = substr($binenc, $this->ks);
/* Initialize encryption module for decryption */
mcrypt_generic_init($this->td, $this->salt, $this->iv);
/* Decrypt encrypted string */
$decrypted = mdecrypt_generic($this->td, $binstr);
/* Terminate decryption handle and close module */
mcrypt_generic_deinit($this->td);
mcrypt_module_close($this->td);
$this->decStr = trim($decrypted);
}
}
I suggest you not only encrypt but also sign the data. If you don't sign the data, you won't be able to tell reliably whether the user modified the data. Also, to avoid replay you may want to add some timestamp/validity period information into the data.
If you don't want your users to read it don't put it in a cookie;
In stead use Session's with a cookie that stays for a longer time. This way the data stays on the server and not at the computer of the user.
See this article about persistant sessions
For encryption example see "symmetric encryption" section in http://www.osix.net/modules/article/?id=606.
To prevent unauthorized modification, use HMAC: http://php.net/hash-hmac, and about hmac in general: http://en.wikipedia.org/wiki/HMAC, http://en.wikipedia.org/wiki/Message_authentication_code
And if you don't have to, don't store sensitive data in a cookie, even encrypted. You may want to read more about "data indirection".
If you absolutely must do this then you can use the symmetric encryption functionality in mcrypt
.
http://php.net/mcrypt