Ubiquity 2.5.2
php rapid development framework
Loading...
Searching...
No Matches
Encryption.php
Go to the documentation of this file.
1<?php
3
7
19
20 const AES128 = 'AES-128-CBC';
21
22 const AES192 = 'AES-192-CBC';
23
24 const AES256 = 'AES-256-CBC';
25
26 private static $acceptedCiphers = [
27 32 => self::AES128,
28 48 => self::AES192,
29 64 => self::AES256
30 ];
31
37 protected $key;
38
44 protected $cipher;
45
55 public function __construct(?string $key = null, ?string $cipher = null) {
56 $this->key = $key;
57 $this->cipher = $cipher;
58 }
59
60 public function initializeKeyAndCipher() {
61 if (isset($this->key) && ! isset($this->cipher)) {
62 $this->cipher = self::getCipherFromKey($this->key);
63 } elseif (! isset($this->key)) {
64 $this->cipher ??= self::AES128;
65 $this->key = self::generateKey($this->cipher);
66 }
67 if (! self::isValidKey($this->key, $this->cipher)) {
68 throw new EncryptionKeyException("The encryption key size is not valid for {$this->cipher}.");
69 }
70 }
71
72 public static function getCipherFromKey(string $key) {
73 $size = \strlen($key);
74 if (isset(self::$acceptedCiphers[$size])) {
75 return self::$acceptedCiphers[$size];
76 }
77 throw new EncryptionKeyException("The encryption key has not a valid size ({$size})");
78 }
79
87 protected function hash($iv, $value): string {
88 return \hash_hmac('sha256', $iv . $value, $this->key);
89 }
90
97 protected function getJsonPayload($payload) {
98 $payload = \json_decode(\base64_decode($payload), true);
99 if (! $this->isValidPayload($payload)) {
100 throw new DecryptException('The payload is invalid.');
101 }
102 if (! $this->isValidMac($payload)) {
103 throw new DecryptException('The MAC control is invalid.');
104 }
105
106 return $payload;
107 }
108
115 protected function isValidPayload($payload) {
116 return \is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) && \strlen(\base64_decode($payload['iv'], true)) === \openssl_cipher_iv_length($this->cipher);
117 }
118
125 protected function isValidMac(array $payload) {
126 $calculated = $this->calculateMac($payload, $bytes = random_bytes(16));
127 return \hash_equals(\hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated);
128 }
129
137 protected function calculateMac($payload, $bytes) {
138 return \hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true);
139 }
140
149 public function encrypt($value, $serialize = true): string {
150 $iv = \random_bytes(\openssl_cipher_iv_length($this->cipher));
151 $value = \openssl_encrypt($serialize ? \serialize($value) : $value, $this->cipher, $this->key, 0, $iv);
152 if ($value === false) {
153 throw new EncryptException('Could not encrypt the data with openssl.');
154 }
155
156 $mac = $this->hash($iv = base64_encode($iv), $value);
157 $json = \json_encode(\compact('iv', 'value', 'mac'), JSON_UNESCAPED_SLASHES);
158 if (\json_last_error() !== \JSON_ERROR_NONE) {
159 throw new EncryptException('Could not json_encode the data.');
160 }
161
162 return \base64_encode($json);
163 }
164
171 public function encryptString(string $value): string {
172 return $this->encrypt($value, false);
173 }
174
183 public function decrypt(string $payload, $unserialize = true) {
184 $payload = $this->getJsonPayload($payload);
185 $iv = base64_decode($payload['iv']);
186 $decrypted = \openssl_decrypt($payload['value'], $this->cipher, $this->key, 0, $iv);
187
188 if ($decrypted === false) {
189 throw new DecryptException('Could not decrypt the data.');
190 }
191
192 return $unserialize ? unserialize($decrypted) : $decrypted;
193 }
194
202 public function decryptString($payload) {
203 return $this->decrypt($payload, false);
204 }
205
213 public static function isValidKey(string $key, string $cipher): bool {
214 $length = \strlen($key);
215 return isset(self::$acceptedCiphers[$length]) && self::$acceptedCiphers[$length] === $cipher;
216 }
217
224 public static function generateKey(string $cipher): string {
225 $sizeMethods = \array_flip(self::$acceptedCiphers);
226 return \bin2hex(\random_bytes($sizeMethods[$cipher] / 2));
227 }
228
233 public function getKey() {
234 return $this->key;
235 }
236
241 public function getCipher() {
242 return $this->cipher;
243 }
244
245 public static function getMethods(?bool $aliases = null): array {
246 return \openssl_get_cipher_methods($aliases);
247 }
248}
249
Ubiquity\security\data$Encryption This class is part of Ubiquity Inspired from illuminate/encryption ...
static isValidKey(string $key, string $cipher)
Check if the given key and cipher combination is valid.
static generateKey(string $cipher)
Generate a new key for the given cipher.
static getCipherFromKey(string $key)
hash($iv, $value)
Create a MAC for the given value.
isValidMac(array $payload)
Check if the MAC for the given payload is valid.
__construct(?string $key=null, ?string $cipher=null)
Create a new encrypter instance.
getJsonPayload($payload)
Get the JSON array from the given payload.
encryptString(string $value)
Encrypt a string without serialization.
calculateMac($payload, $bytes)
Calculate the hash of the given payload.
encrypt($value, $serialize=true)
Encrypt the given value.
isValidPayload($payload)
Check that the encryption payload is valid.
decrypt(string $payload, $unserialize=true)
Decrypt the given value.
decryptString($payload)
Decrypt the given string without unserialization.
static getMethods(?bool $aliases=null)