Spaces:
No application file
No application file
namespace Mautic\CoreBundle\Helper; | |
use Mautic\CoreBundle\Security\Cryptography\Cipher\Symmetric\SymmetricCipherInterface; | |
use Mautic\CoreBundle\Security\Exception\Cryptography\Symmetric\InvalidDecryptionException; | |
class EncryptionHelper | |
{ | |
/** | |
* @var SymmetricCipherInterface[] | |
*/ | |
private ?array $availableCiphers = null; | |
/** | |
* @var string | |
*/ | |
private $key; | |
public function __construct( | |
CoreParametersHelper $coreParametersHelper | |
) { | |
$nonCipherArgs = 1; | |
for ($i = $nonCipherArgs; $i < func_num_args(); ++$i) { | |
$possibleCipher = func_get_arg($i); | |
if (!($possibleCipher instanceof SymmetricCipherInterface)) { | |
throw new \InvalidArgumentException($possibleCipher::class.' has to implement '.SymmetricCipherInterface::class); | |
} | |
if (!$possibleCipher->isSupported()) { | |
continue; | |
} | |
$this->availableCiphers[] = $possibleCipher; | |
} | |
if (!$this->availableCiphers || 0 === count($this->availableCiphers)) { | |
throw new \RuntimeException('None of possible cryptography libraries is supported'); | |
} | |
$this->key = $coreParametersHelper->get('mautic.secret_key'); | |
} | |
/** | |
* Returns a 64 character string. | |
*/ | |
public static function generateKey(): string | |
{ | |
return hash('sha256', uniqid(mt_rand(), true)); | |
} | |
/** | |
* Encrypt string. | |
* | |
* @param mixed $data | |
*/ | |
public function encrypt($data): string | |
{ | |
$encryptionCipher = reset($this->availableCiphers); | |
$initVector = $encryptionCipher->getRandomInitVector(); | |
$encrypted = $encryptionCipher->encrypt(serialize($data), $this->key, $initVector); | |
return base64_encode($encrypted).'|'.base64_encode($initVector); | |
} | |
/** | |
* Decrypt string. | |
* Returns false in case of failed decryption. | |
* | |
* @param string $data | |
* @param bool $mainDecryptOnly | |
* | |
* @return mixed|false | |
*/ | |
public function decrypt($data, $mainDecryptOnly = false) | |
{ | |
$encryptData = explode('|', $data); | |
$encryptedMessage = base64_decode($encryptData[0]); | |
$initVector = base64_decode($encryptData[1]); | |
$mainTried = false; | |
foreach ($this->availableCiphers as $availableCipher) { | |
if ($mainDecryptOnly && $mainTried) { | |
return false; | |
} | |
try { | |
return Serializer::decode($availableCipher->decrypt($encryptedMessage, $this->key, $initVector)); | |
} catch (InvalidDecryptionException) { | |
} | |
$mainTried = true; | |
} | |
return false; | |
} | |
} | |