Permalink
Browse files

Add support for aes encrypted cookies.

With Security supporting AES encryption it is also ideal to have AES
compatible cookies. Refactor and simplify code. Dynamic invocation of
static method is a bit obtuse and the various methods don't all have the
same arguments.
  • Loading branch information...
1 parent 215d43e commit 005a7d841d0843f1e8d8c808dd965ee6323c03ce @markstory markstory committed Aug 28, 2013
Showing with 46 additions and 22 deletions.
  1. +46 −22 lib/Cake/Controller/Component/CookieComponent.php
@@ -132,7 +132,9 @@ class CookieComponent extends Component {
* Type of encryption to use.
*
* Currently two methods are available: cipher and rijndael
- * Defaults to Security::cipher();
+ * Defaults to Security::cipher(). Cipher is horribly insecure and only
+ * the default because of backwards compatibility. In new applications you should
+ * always change this to 'aes' or 'rijndael'.
*
* @var string
*/
@@ -364,10 +366,11 @@ public function destroy() {
public function type($type = 'cipher') {
$availableTypes = array(
'cipher',
- 'rijndael'
+ 'rijndael',
+ 'aes'
);
if (!in_array($type, $availableTypes)) {
- trigger_error(__d('cake_dev', 'You must use cipher or rijndael for cookie encryption type'), E_USER_WARNING);
+ trigger_error(__d('cake_dev', 'You must use cipher, rijndael or aes for cookie encryption type'), E_USER_WARNING);
$type = 'cipher';
}
$this->_type = $type;
@@ -455,12 +458,20 @@ protected function _encrypt($value) {
if (is_array($value)) {
$value = $this->_implode($value);
}
-
- if ($this->_encrypted === true) {
- $type = $this->_type;
- $value = "Q2FrZQ==." . base64_encode(Security::$type($value, $this->key, 'encrypt'));
+ if (!$this->_encrypted) {
+ return $value;
+ }
+ $prefix = "Q2FrZQ==.";
+ if ($this->_type === 'rijndael') {
+ $cipher = Security::rijndael($value, $this->key, 'encrypt');
+ }
+ if ($this->_type === 'cipher') {
+ $cipher = Security::cipher($value, $this->key);
+ }
+ if ($this->_type === 'aes') {
+ $cipher = Security::encrypt($value, $this->key);
}
- return $value;
+ return $prefix . base64_encode($cipher);
}
/**
@@ -476,28 +487,41 @@ protected function _decrypt($values) {
foreach ((array)$values as $name => $value) {
if (is_array($value)) {
foreach ($value as $key => $val) {
- $pos = strpos($val, 'Q2FrZQ==.');
- $decrypted[$name][$key] = $this->_explode($val);
-
- if ($pos !== false) {
- $val = substr($val, 8);
- $decrypted[$name][$key] = $this->_explode(Security::$type(base64_decode($val), $this->key, 'decrypt'));
- }
+ $decrypted[$name][$key] = $this->_decode($val);
}
} else {
- $pos = strpos($value, 'Q2FrZQ==.');
- $decrypted[$name] = $this->_explode($value);
-
- if ($pos !== false) {
- $value = substr($value, 8);
- $decrypted[$name] = $this->_explode(Security::$type(base64_decode($value), $this->key, 'decrypt'));
- }
+ $decrypted[$name] = $this->_decode($value);
}
}
return $decrypted;
}
/**
+ * Decodes and decrypts a single value.
+ *
+ * @param string $value The value to decode & decrypt.
+ * @return string Decoded value.
+ */
+ protected function _decode($value) {
+ $prefix = 'Q2FrZQ==.';
+ $pos = strpos($value, $prefix);
+ if ($pos === false) {
+ return $this->_explode($value);
+ }
+ $value = base64_decode(substr($value, strlen($prefix)));
+ if ($this->_type === 'rijndael') {
+ $plain = Security::rijndael($value, $this->key, 'decrypt');
+ }
+ if ($this->_type === 'cipher') {
+ $plain = Security::cipher($value, $this->key);
+ }
+ if ($this->_type === 'aes') {
+ $plain = Security::decrypt($value, $this->key);
+ }
+ return $this->_explode($plain);
+ }
+
+/**
* Implode method to keep keys are multidimensional arrays
*
* @param array $array Map of key and values

0 comments on commit 005a7d8

Please sign in to comment.