Update: French version here.
Note for newcomers : you should first read the previous post introducing secure cookies : Security, Cookies and the REST.
So... where were we ? There is a secure protocol for cookies (see Alex X. Liu's paper for details) :
username|expiration time|(data)k|HMAC(username|expiration time|data|SSL session key, k)Where :
- username is the username (or an unique identifier)
- expiration time : the cookie's expiration time
- (data)k is the result of a symmetric cryptographic (ex: Rijndael) function on data with key k.
- data is the data you want to store in the cookie
- k is the result of HMAC(username|expiration time, sk)
- sk is the server's secret key
- SSL session key is the SSL session key.
This protocol is secure :
- It protects your cookie against replay attacks : SSL session key is unique to your SSL session. So a malicious user can't send the same cookie in another SSL session, it'll be invalid.
- It protects the data confidentiality with a symmetric cryptographic function : data is stored encrypted
- It protects the data integrity with an HMAC function
- It protects your secret key against volume attacks
But it needs some flexibility for a common usage :
- SSL Feature is cool, it protects you against replay attacks, but :
- Maybe you have no HTTPS access to your application
- Cookie's lifetime is limited to the SSL session lifetime
- Data encryption is cool, but maybe you're not interested in this feature. If you are not, it expands the size of the cookie for nothing. For example: if data is encrypted with with Rijndael/256 bits key, the encrypted value will be at least 32 byte long, even if your data is 1 byte long
So, it may be cool to have a configurable class to manage secure cookies. By configurable, I mean to be able to :
- enable/disable SSL feature
- enable/disable the data encryption feature
- choose the encryption algorithm
I've done a PHP class which have all these functionality. You can download it here.
Usage :Initialization
include('BigOrNot_CookieManager.php'); $secretKey = 'Cei4Wai4ohcoo3daeHooFiek5Nah3Eet'; $manager = new BigOrNot_CookieManager($secretKey);
All you have to do is to provide a secret key. To generate a key you can use this shell command :
The default configuration is :
- High confidentiality (data encryption) : enabled option name : high_confidentiality (bool)
- Cipher : MCRYPT_RIJNDAEL_256 (Rijndael 256) option name : mcrypt_algorithm (see mcrypt documentation)
- Mode : MCRYPT_MODE_CBC (CBC) option name : mcrypt_mode (see mcrypt_documentation)
- SSL session key : disabled option name : enable_ssl (bool)
You can (optionally) give a second argument to the constructor to configure the class. For example, if you want to disable data encryption you can do that :
include('BigOrNot_CookieManager.php'); $secretKey = 'Cei4Wai4ohcoo3daeHooFiek5Nah3Eet'; $config = array('high_confidentiality' => false); $manager = new BigOrNot_CookieManager($secretKey, $config);
Set a secure cookie
$expire = time() + 86400; $value = $manager->setCookie('cookieName', 'value', 'username');Read source for more details on possible arguments. (You can give all regular setcookie() arguments)
Read/verify a cookie value
$value = $manager->getCookieValue('cookieName');If cookie is invalid, it will be deleted automatically. If you don't like this behaviour, you can give "false" as a second argument.
Delete a cookie
$manager->deleteCookie('cookieName');
Enjoy ! Source file is commented if you need more informations. If you have questions, remarks, bug reports, post a comment :)
Note: There is a class to use the same protocol with Django (Python) here.