The problem is that the cookie is on the visitor's machine and is available easily and anyone can edit it.
Imagine my id is "Peter". I'm on your site with login. I'll take a look at the Cookie and see inside "id = Peter".
I'll ask a colleague which one and his id, he will tell me that it is (for example) "max". I'm going to put a cookie with "id = max" and I could connect myself like it.
It's not very safe ...
This requires the cookie to contain enough information for you to know who is logged in (not only your id, but also other information you can mix to see if they are correct, eg visitor id, your age, your zip code etc ...) and also that the cookie is encrypted.
The difficulty is that you can not have asymmetric encryption because you will have to read the cookie to take information.
Therefore, you must determine what you need to store, prepare the data as a string, encrypt the string and put it in the cookie.
After reading, you will have to decipher the cookie and remove the "string" and check the integrity. You can for example encrypt according to the Cookie submission date, the location of the visitor etc ... So if someone managed to "break" the cookie, he will also need to know the geographic location of which he wants to usurp identity, which quickly becomes complicated.
Here is a small class of encryption that can help you. I obviously can not show you the full path I use to encrypt my cookies.
class Chiffrement
{
// Cipher:
// cast-128 gost rijndael-128 twofish arcfour cast-256 loki97 rijndael-192
// saferplus wake blowfish-compat des rijndael-256 serpent xtea blowfish
// enigma rc2 tripledes
// Modes:
// cbc cfb ctr ecb ncfb nofb ofb stream
private static $cipher = MCRYPT_RIJNDAEL_256; // Cipher
private static $mode = 'cbc'; // Mode (blocoss)
public static function crypt($data,$key)
{
$keyHash = md5($key);
$key = substr($keyHash, 0, mcrypt_get_key_size(self::$cipher, self::$mode) );
$iv = substr($keyHash, 0, mcrypt_get_block_size(self::$cipher, self::$mode) );
$data = mcrypt_encrypt(self::$cipher, $key, $data, self::$mode, $iv);
return base64_encode($data);
}
public static function decrypt($data,$key)
{
$keyHash = md5($key);
$key = substr($keyHash, 0, mcrypt_get_key_size(self::$cipher, self::$mode) );
$iv = substr($keyHash, 0, mcrypt_get_block_size(self::$cipher, self::$mode) );
$data = base64_decode($data);
return mcrypt_decrypt(self::$cipher, $key, $data, self::$mode, $iv);
}
}
I will complete to answer in cometario: in the case of databases, sessions, and very difficult to know where the data is. And really, it does not matter. If a person can do a SQL injection, they do not need to know "exactly where" the data is: they need to know how to read the data. Enough.
So, find that everything is right because the data not on the server is a joke: what you need and protect the lit, then avoid "giving the house key". The difficulty is that the visitor ... must have the key to access! It means the key will be in the browser.
The biggest problem is the connection between the key and the data and the main question and how to avoid copying the key, and worse, how to prevent a person from understanding the key system to make a copy equal to what It looks the same. "
Analyzing the Cookie in your browser allows you to easily see that it has to be unprotected: you will var your id for example. With software like link you can modify the cookie.
This means that you need to modify the cookie to avoid modification, rather than the Id, to create a link between the cookie data.
The goal will never be to put all the info in the cookie: the goal is to prevent the modification of the cookie and have the ability, on the server side, to know that the key is stuck. Then, with a core key, reading the BDD data is easy.