2023-10-06 11:43:34 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Lib\Tools;
|
|
|
|
|
|
|
|
use Cake\Core\Configure;
|
2023-10-11 10:38:17 +02:00
|
|
|
use JsonSerializable;
|
2023-10-06 11:43:34 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class for ondemand encryption of JSON serialized value
|
|
|
|
*/
|
|
|
|
class EncryptedValue implements JsonSerializable
|
|
|
|
{
|
|
|
|
const ENCRYPTED_MAGIC = "\x1F\x1D";
|
|
|
|
|
|
|
|
/** @var string */
|
|
|
|
private $value;
|
|
|
|
|
|
|
|
/** @var bool */
|
|
|
|
private $isJson;
|
|
|
|
|
|
|
|
public function __construct($value, $isJson = false)
|
|
|
|
{
|
|
|
|
$this->value = $value;
|
|
|
|
$this->isJson = $isJson;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
* @throws JsonException
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
2024-02-06 14:31:25 +01:00
|
|
|
public function decrypt($key = false)
|
2023-10-06 11:43:34 +02:00
|
|
|
{
|
2023-12-17 12:31:06 +01:00
|
|
|
if (!$key) {
|
|
|
|
$key = Configure::read('Security.encryption_key');
|
|
|
|
}
|
2024-02-06 14:31:25 +01:00
|
|
|
if (!$key) {
|
|
|
|
return '';
|
|
|
|
}
|
2023-12-17 12:31:06 +01:00
|
|
|
$decrypt = BetterSecurity::decrypt(substr($this->value, 2), $key);
|
2023-10-06 11:43:34 +02:00
|
|
|
return $this->isJson ? JsonTool::decode($decrypt) : $decrypt;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function __toString()
|
|
|
|
{
|
|
|
|
return $this->decrypt();
|
|
|
|
}
|
|
|
|
|
2023-10-11 10:38:17 +02:00
|
|
|
public function jsonSerialize(): mixed
|
2023-10-06 11:43:34 +02:00
|
|
|
{
|
|
|
|
return $this->decrypt();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Encrypt provided string if encryption is enabled. If not enabled, input value will be returned.
|
|
|
|
* @param string $value
|
|
|
|
* @return string
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
2024-02-06 14:31:25 +01:00
|
|
|
public static function encryptIfEnabled($value, $key = false)
|
2023-10-06 11:43:34 +02:00
|
|
|
{
|
2023-12-17 12:31:06 +01:00
|
|
|
if (!$key) {
|
|
|
|
$key = Configure::read('Security.encryption_key');
|
|
|
|
}
|
2023-10-06 11:43:34 +02:00
|
|
|
if ($key) {
|
|
|
|
return EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($value, $key);
|
|
|
|
}
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
2023-12-17 12:31:06 +01:00
|
|
|
/**
|
|
|
|
* Decrypt if value is encrypted. If not encrypted, input value will be returned.
|
|
|
|
* @param string $value
|
|
|
|
* @return string
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
2024-02-06 14:31:25 +01:00
|
|
|
public static function decryptIfEncrypted($value, $key = false)
|
2023-12-17 12:31:06 +01:00
|
|
|
{
|
2024-02-06 14:31:25 +01:00
|
|
|
if (is_resource($value)) {
|
2023-12-17 12:31:06 +01:00
|
|
|
$value = stream_get_contents($value);
|
2024-02-06 14:31:25 +01:00
|
|
|
}
|
2023-12-17 12:31:06 +01:00
|
|
|
if (EncryptedValue::isEncrypted($value)) {
|
|
|
|
$self = new EncryptedValue($value);
|
2024-02-06 14:31:25 +01:00
|
|
|
return $self->decrypt($key);
|
2023-12-17 12:31:06 +01:00
|
|
|
} else {
|
2024-02-06 14:31:25 +01:00
|
|
|
return trim($value, "\x00");
|
2023-12-17 12:31:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-06 11:43:34 +02:00
|
|
|
/**
|
|
|
|
* Check if value is encrypted (starts with encrypted magic)
|
|
|
|
* @param string $value
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function isEncrypted($value)
|
|
|
|
{
|
|
|
|
return substr($value, 0, 2) === EncryptedValue::ENCRYPTED_MAGIC;
|
|
|
|
}
|
|
|
|
}
|