/
CookieCryptTrait.php
209 lines (180 loc) · 4.76 KB
/
CookieCryptTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.5.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Http\Cookie;
use Cake\Utility\Security;
use RuntimeException;
/**
* Cookie Crypt Trait.
*
* Provides the encrypt/decrypt logic.
*/
trait CookieCryptTrait
{
/**
* Valid cipher names for encrypted cookies.
*
* @var array
*/
protected $_validCiphers = [
'aes'
];
/**
* Encryption cipher
*
* @param string|bool
*/
protected $encryptionCipher = 'aes';
/**
* The key for encrypting and decrypting the cookie
*
* @var string
*/
protected $encryptionKey = '';
/**
* Prefix of the encrypted string
*
* @var string
*/
protected $encryptedStringPrefix = 'Q2FrZQ==.';
/**
* Sets the encryption cipher
*
* @param string $cipher Cipher
* @return $this
*/
public function setEncryptionCipher($cipher)
{
$this->checkCipher($cipher);
$this->encryptionCipher = $cipher;
return $this;
}
/**
* Check if encryption is enabled
*
* @return bool
*/
public function isEncryptionEnabled()
{
return is_string($this->encryptionCipher);
}
/**
* Disables the encryption
*
* @return $this
*/
public function disableEncryption()
{
$this->encryptionCipher = false;
return $this;
}
/**
* Sets the encryption key
*
* @param string $key Encryption key
* @return $this
*/
public function setEncryptionKey($key)
{
$this->encryptionKey = $key;
return $this;
}
/**
* Returns the encryption key to be used.
*
* @return string
*/
public function getEncryptionKey()
{
if ($this->encryptionKey === null) {
return Security::salt();
}
return $this->encryptionKey;
}
/**
* Encrypts $value using public $type method in Security class
*
* @param string|array $value Value to encrypt
* @return string Encoded values
*/
protected function _encrypt($value)
{
if (is_array($value)) {
$value = $this->_flatten($value);
}
$encrypt = $this->encryptionCipher;
if ($encrypt === false) {
throw new RuntimeException('Encryption is disabled, no cipher provided.');
}
$cipher = null;
$key = $this->getEncryptionKey();
if ($encrypt === 'aes') {
$cipher = Security::encrypt($value, $key);
}
return $this->encryptedStringPrefix . base64_encode($cipher);
}
/**
* Helper method for validating encryption cipher names.
*
* @param string $encrypt The cipher name.
* @return void
* @throws \RuntimeException When an invalid cipher is provided.
*/
protected function checkCipher($encrypt)
{
if (!in_array($encrypt, $this->_validCiphers)) {
$msg = sprintf(
'Invalid encryption cipher. Must be one of %s.',
implode(', ', $this->_validCiphers)
);
throw new RuntimeException($msg);
}
}
/**
* Decrypts $value using public $type method in Security class
*
* @param string|array $values Values to decrypt
* @return string|array Decrypted values
*/
protected function _decrypt($values)
{
if (is_string($values)) {
return $this->_decode($values);
}
$decrypted = [];
foreach ($values as $name => $value) {
$decrypted[$name] = $this->_decode($value);
}
return $decrypted;
}
/**
* Decodes and decrypts a single value.
*
* @param string $value The value to decode & decrypt.
* @return string|array Decoded values.
*/
protected function _decode($value)
{
if (!$this->isEncryptionEnabled()) {
return $this->_expand($value);
}
$key = $this->getEncryptionKey();
$encrypt = $this->encryptionCipher;
$value = base64_decode(substr($value, strlen($this->encryptedStringPrefix)));
if ($encrypt === 'aes') {
$value = Security::decrypt($value, $key);
}
return $this->_expand($value);
}
}