Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b69390fa2 | ||
|
|
0524d8ac1b | ||
|
|
e933022671 | ||
|
|
c549d34e65 |
@@ -1,12 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phive xmlns="https://phar.io/phive">
|
<phive xmlns="https://phar.io/phive">
|
||||||
<phar name="phpunit" version="^9.6" installed="9.6.19" location="./tools/phpunit" copy="false"/>
|
<phar name="phpunit" version="^9.6" installed="9.6.19" location="./tools/phpunit" copy="false"/>
|
||||||
<phar name="phpcbf" version="^3.7.2" installed="3.9.1" location="./tools/phpcbf" copy="false"/>
|
<phar name="phpcbf" version="^3.7.2" installed="3.10.0" location="./tools/phpcbf" copy="false"/>
|
||||||
<phar name="phpcs" version="^3.7.2" installed="3.9.1" location="./tools/phpcs" copy="false"/>
|
<phar name="phpcs" version="^3.7.2" installed="3.10.0" location="./tools/phpcs" copy="false"/>
|
||||||
<phar name="phpstan" version="^1.10.37" installed="1.10.67" location="./tools/phpstan" copy="false"/>
|
<phar name="phpstan" version="^1.10.37" installed="1.11.1" location="./tools/phpstan" copy="false"/>
|
||||||
<phar name="phan" version="^5.4.2" installed="5.4.3" location="./tools/phan" copy="false"/>
|
<phar name="phan" version="^5.4.2" installed="5.4.3" location="./tools/phan" copy="false"/>
|
||||||
<phar name="psalm" version="^5.15.0" installed="5.23.1" location="./tools/psalm" copy="false"/>
|
<phar name="psalm" version="^5.15.0" installed="5.24.0" location="./tools/psalm" copy="false"/>
|
||||||
<phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/>
|
<phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/>
|
||||||
<phar name="phpdocumentor" version="^3.4.2" installed="3.4.3" location="./tools/phpDocumentor" copy="false"/>
|
<phar name="phpdocumentor" version="^3.4.2" installed="3.4.3" location="./tools/phpDocumentor" copy="false"/>
|
||||||
<phar name="php-cs-fixer" version="^3.34.1" installed="3.53.0" location="./tools/php-cs-fixer" copy="false"/>
|
<phar name="php-cs-fixer" version="^3.34.1" installed="3.57.2" location="./tools/php-cs-fixer" copy="false"/>
|
||||||
</phive>
|
</phive>
|
||||||
|
|||||||
@@ -46,12 +46,34 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
public function testEncryptDecryptSuccess(string $input, string $expected): void
|
public function testEncryptDecryptSuccess(string $input, string $expected): void
|
||||||
{
|
{
|
||||||
$key = CreateKey::generateRandomKey();
|
$key = CreateKey::generateRandomKey();
|
||||||
$encrypted = SymmetricEncryption::encrypt($input, $key);
|
|
||||||
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
|
// test class
|
||||||
|
$crypt = new SymmetricEncryption($key);
|
||||||
|
$encrypted = $crypt->encrypt($input);
|
||||||
|
$decrypted = $crypt->decrypt($encrypted);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$decrypted,
|
||||||
|
'Class call',
|
||||||
|
);
|
||||||
|
|
||||||
|
// test indirect
|
||||||
|
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
|
||||||
|
$decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$decrypted,
|
||||||
|
'Class Instance call',
|
||||||
|
);
|
||||||
|
|
||||||
|
// test static
|
||||||
|
$encrypted = SymmetricEncryption::encryptKey($input, $key);
|
||||||
|
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
$decrypted
|
$decrypted,
|
||||||
|
'Static call',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +108,24 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
public function testEncryptFailed(string $input, string $exception_message): void
|
public function testEncryptFailed(string $input, string $exception_message): void
|
||||||
{
|
{
|
||||||
$key = CreateKey::generateRandomKey();
|
$key = CreateKey::generateRandomKey();
|
||||||
$encrypted = SymmetricEncryption::encrypt($input, $key);
|
|
||||||
$wrong_key = CreateKey::generateRandomKey();
|
$wrong_key = CreateKey::generateRandomKey();
|
||||||
|
|
||||||
|
// wrong key in class call
|
||||||
|
$crypt = new SymmetricEncryption($key);
|
||||||
|
$encrypted = $crypt->encrypt($input);
|
||||||
$this->expectExceptionMessage($exception_message);
|
$this->expectExceptionMessage($exception_message);
|
||||||
SymmetricEncryption::decrypt($encrypted, $wrong_key);
|
$crypt->setKey($key);
|
||||||
|
$crypt->decrypt($encrypted);
|
||||||
|
|
||||||
|
// class instance
|
||||||
|
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($input);
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::getInstance($wrong_key)->decrypt($encrypted);
|
||||||
|
|
||||||
|
// class static
|
||||||
|
$encrypted = SymmetricEncryption::encryptKey($input, $key);
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::decryptKey($encrypted, $wrong_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,7 +143,6 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
'too short hex key' => [
|
'too short hex key' => [
|
||||||
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
|
'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
|
||||||
'excpetion_message' => 'Key is not the correct size (must be '
|
'excpetion_message' => 'Key is not the correct size (must be '
|
||||||
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -126,13 +161,33 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testWrongKey(string $key, string $exception_message): void
|
public function testWrongKey(string $key, string $exception_message): void
|
||||||
{
|
{
|
||||||
$this->expectExceptionMessage($exception_message);
|
|
||||||
SymmetricEncryption::encrypt('test', $key);
|
|
||||||
// we must encrypt valid thing first so we can fail with the wrong kjey
|
|
||||||
$enc_key = CreateKey::generateRandomKey();
|
$enc_key = CreateKey::generateRandomKey();
|
||||||
$encrypted = SymmetricEncryption::encrypt('test', $enc_key);
|
|
||||||
|
// class
|
||||||
|
$crypt = new SymmetricEncryption($key);
|
||||||
$this->expectExceptionMessage($exception_message);
|
$this->expectExceptionMessage($exception_message);
|
||||||
SymmetricEncryption::decrypt($encrypted, $key);
|
$crypt->encrypt('test');
|
||||||
|
$crypt->setKey($enc_key);
|
||||||
|
$encrypted = $crypt->encrypt('test');
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
$crypt->setKey($key);
|
||||||
|
$crypt->decrypt($encrypted);
|
||||||
|
|
||||||
|
// class instance
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::getInstance($key)->encrypt('test');
|
||||||
|
// we must encrypt valid thing first so we can fail with the wrong key
|
||||||
|
$encrypted = SymmetricEncryption::getInstance($enc_key)->encrypt('test');
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::getInstance($key)->decrypt($encrypted);
|
||||||
|
|
||||||
|
// class static
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::encryptKey('test', $key);
|
||||||
|
// we must encrypt valid thing first so we can fail with the wrong key
|
||||||
|
$encrypted = SymmetricEncryption::encryptKey('test', $enc_key);
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::decryptKey($encrypted, $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,7 +200,7 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
return [
|
return [
|
||||||
'too short ciphertext' => [
|
'too short ciphertext' => [
|
||||||
'input' => 'short',
|
'input' => 'short',
|
||||||
'exception_message' => 'Invalid ciphertext (too short)'
|
'exception_message' => 'Decipher message failed: '
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -164,8 +219,18 @@ final class CoreLibsSecuritySymmetricEncryptionTest extends TestCase
|
|||||||
public function testWrongCiphertext(string $input, string $exception_message): void
|
public function testWrongCiphertext(string $input, string $exception_message): void
|
||||||
{
|
{
|
||||||
$key = CreateKey::generateRandomKey();
|
$key = CreateKey::generateRandomKey();
|
||||||
|
// class
|
||||||
|
$crypt = new SymmetricEncryption($key);
|
||||||
$this->expectExceptionMessage($exception_message);
|
$this->expectExceptionMessage($exception_message);
|
||||||
SymmetricEncryption::decrypt($input, $key);
|
$crypt->decrypt($input);
|
||||||
|
|
||||||
|
// class instance
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::getInstance($key)->decrypt($input);
|
||||||
|
|
||||||
|
// class static
|
||||||
|
$this->expectExceptionMessage($exception_message);
|
||||||
|
SymmetricEncryption::decryptKey($input, $key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/home/clemens/.phive/phars/php-cs-fixer-3.53.0.phar
|
/home/clemens/.phive/phars/php-cs-fixer-3.57.2.phar
|
||||||
@@ -1 +1 @@
|
|||||||
/home/clemens/.phive/phars/phpcbf-3.9.1.phar
|
/home/clemens/.phive/phars/phpcbf-3.10.0.phar
|
||||||
@@ -1 +1 @@
|
|||||||
/home/clemens/.phive/phars/phpcs-3.9.1.phar
|
/home/clemens/.phive/phars/phpcs-3.10.0.phar
|
||||||
@@ -1 +1 @@
|
|||||||
/home/clemens/.phive/phars/phpstan-1.10.67.phar
|
/home/clemens/.phive/phars/phpstan-1.11.1.phar
|
||||||
@@ -1 +1 @@
|
|||||||
/home/clemens/.phive/phars/psalm-5.23.1.phar
|
/home/clemens/.phive/phars/psalm-5.24.0.phar
|
||||||
@@ -40,16 +40,33 @@ $key = CreateKey::generateRandomKey();
|
|||||||
print "Secret Key: " . $key . "<br>";
|
print "Secret Key: " . $key . "<br>";
|
||||||
|
|
||||||
$string = "I a some deep secret";
|
$string = "I a some deep secret";
|
||||||
$encrypted = SymmetricEncryption::encrypt($string, $key);
|
//
|
||||||
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
|
$crypt = new SymmetricEncryption($key);
|
||||||
|
$encrypted = $crypt->encrypt($string);
|
||||||
|
$decrypted = $crypt->decrypt($encrypted);
|
||||||
|
print "[C] Encrypted: " . $encrypted . "<br>";
|
||||||
|
print "[C] Decrytped: " . $decrypted . "<br>";
|
||||||
|
$encrypted = SymmetricEncryption::getInstance($key)->encrypt($string);
|
||||||
|
$decrypted = SymmetricEncryption::getInstance($key)->decrypt($encrypted);
|
||||||
|
print "[S] Original: " . $string . "<br>";
|
||||||
|
print "[S] Encrypted: " . $encrypted . "<br>";
|
||||||
|
print "[S] Decrytped: " . $decrypted . "<br>";
|
||||||
|
$encrypted = SymmetricEncryption::encryptKey($string, $key);
|
||||||
|
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
|
||||||
|
print "[SS] Encrypted: " . $encrypted . "<br>";
|
||||||
|
print "[SS] Decrytped: " . $decrypted . "<br>";
|
||||||
|
|
||||||
print "Original: " . $string . "<br>";
|
print "<br>INIT KEY MISSING<br>";
|
||||||
print "Encrypted: " . $encrypted . "<br>";
|
try {
|
||||||
print "Decrytped: " . $decrypted . "<br>";
|
$crypt = new SymmetricEncryption();
|
||||||
|
$encrypted = $crypt->decrypt($string);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
print("Error: " . $e->getMessage() . "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
print "<br>WRONG CIPHERTEXT<br>";
|
print "<br>WRONG CIPHERTEXT<br>";
|
||||||
try {
|
try {
|
||||||
$decrypted = SymmetricEncryption::decrypt('flupper', $key);
|
$decrypted = SymmetricEncryption::decryptKey('flupper', $key);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print "Error: " . $e->getMessage() . "<br>";
|
print "Error: " . $e->getMessage() . "<br>";
|
||||||
}
|
}
|
||||||
@@ -57,7 +74,7 @@ try {
|
|||||||
print "<br>SHORT and WRONG KEY<br>";
|
print "<br>SHORT and WRONG KEY<br>";
|
||||||
$key = 'wrong_key';
|
$key = 'wrong_key';
|
||||||
try {
|
try {
|
||||||
$encrypted = SymmetricEncryption::encrypt($string, $key);
|
$encrypted = SymmetricEncryption::encryptKey($string, $key);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print "Error: " . $e->getMessage() . "<br>";
|
print "Error: " . $e->getMessage() . "<br>";
|
||||||
}
|
}
|
||||||
@@ -65,7 +82,7 @@ try {
|
|||||||
print "<br>INVALID HEX KEY<br>";
|
print "<br>INVALID HEX KEY<br>";
|
||||||
$key = '1cabd5cba9e042f12522f4ff2de5c31d233b';
|
$key = '1cabd5cba9e042f12522f4ff2de5c31d233b';
|
||||||
try {
|
try {
|
||||||
$encrypted = SymmetricEncryption::encrypt($string, $key);
|
$encrypted = SymmetricEncryption::encryptKey($string, $key);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print "Error: " . $e->getMessage() . "<br>";
|
print "Error: " . $e->getMessage() . "<br>";
|
||||||
}
|
}
|
||||||
@@ -73,21 +90,10 @@ try {
|
|||||||
print "<br>WRONG KEY TO DECRYPT<br>";
|
print "<br>WRONG KEY TO DECRYPT<br>";
|
||||||
$key = CreateKey::generateRandomKey();
|
$key = CreateKey::generateRandomKey();
|
||||||
$string = "I a some deep secret";
|
$string = "I a some deep secret";
|
||||||
$encrypted = SymmetricEncryption::encrypt($string, $key);
|
$encrypted = SymmetricEncryption::encryptKey($string, $key);
|
||||||
$key = CreateKey::generateRandomKey();
|
|
||||||
try {
|
|
||||||
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
print "Error: " . $e->getMessage() . "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
print "<br>WRONG KEY TO DECRYPT<br>";
|
|
||||||
$key = CreateKey::generateRandomKey();
|
|
||||||
$string = "I a some deep secret";
|
|
||||||
$encrypted = SymmetricEncryption::encrypt($string, $key);
|
|
||||||
$key = 'wrong_key';
|
$key = 'wrong_key';
|
||||||
try {
|
try {
|
||||||
$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
|
$decrypted = SymmetricEncryption::decryptKey($encrypted, $key);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
print "Error: " . $e->getMessage() . "<br>";
|
print "Error: " . $e->getMessage() . "<br>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,66 +21,82 @@ use SodiumException;
|
|||||||
|
|
||||||
class SymmetricEncryption
|
class SymmetricEncryption
|
||||||
{
|
{
|
||||||
|
/** @var SymmetricEncryption self instance */
|
||||||
|
private static SymmetricEncryption $instance;
|
||||||
|
|
||||||
|
/** @var string bin hex key */
|
||||||
|
private string $key = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init class
|
||||||
|
* if key not passed, key must be set with createKey
|
||||||
|
*
|
||||||
|
* @param string|null|null $key
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
string|null $key = null
|
||||||
|
) {
|
||||||
|
if ($key != null) {
|
||||||
|
$this->setKey($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the singleton self object.
|
||||||
|
* For function wrapper use
|
||||||
|
*
|
||||||
|
* @return SymmetricEncryption object
|
||||||
|
*/
|
||||||
|
public static function getInstance(string|null $key = null): self
|
||||||
|
{
|
||||||
|
if (empty(self::$instance)) {
|
||||||
|
self::$instance = new self($key);
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************
|
||||||
|
* MARK: PRIVATE
|
||||||
|
* *************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create key and check validity
|
* create key and check validity
|
||||||
*
|
*
|
||||||
* @param string $key The key from which the binary key will be created
|
* @param string $key The key from which the binary key will be created
|
||||||
* @return string Binary key string
|
* @return string Binary key string
|
||||||
*/
|
*/
|
||||||
public static function createKey(string $key): string
|
private function createKey(string $key): string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$key = CreateKey::hex2bin($key);
|
$key = CreateKey::hex2bin($key);
|
||||||
} catch (SodiumException $e) {
|
} catch (SodiumException $e) {
|
||||||
throw new \UnexpectedValueException('Invalid hex key');
|
throw new \UnexpectedValueException('Invalid hex key: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
|
if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
|
||||||
throw new \RangeException(
|
throw new \RangeException(
|
||||||
'Key is not the correct size (must be '
|
'Key is not the correct size (must be '
|
||||||
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
|
. SODIUM_CRYPTO_SECRETBOX_KEYBYTES . ' bytes long).'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt a message
|
* Decryption call
|
||||||
*
|
*
|
||||||
* @param string $message Message to encrypt
|
* @param string $encrypted Text to decrypt
|
||||||
* @param string $key Encryption key (as hex string)
|
* @param ?string $key Mandatory encryption key, will throw exception if empty
|
||||||
* @return string
|
* @return string Plain text
|
||||||
* @throws \Exception
|
|
||||||
* @throws \RangeException
|
* @throws \RangeException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
public static function encrypt(string $message, string $key): string
|
private function decryptData(string $encrypted, ?string $key): string
|
||||||
{
|
{
|
||||||
$key = self::createKey($key);
|
if (empty($key)) {
|
||||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
throw new \UnexpectedValueException('Key not set');
|
||||||
|
}
|
||||||
$cipher = base64_encode(
|
$key = $this->createKey($key);
|
||||||
$nonce
|
|
||||||
. sodium_crypto_secretbox(
|
|
||||||
$message,
|
|
||||||
$nonce,
|
|
||||||
$key
|
|
||||||
)
|
|
||||||
);
|
|
||||||
sodium_memzero($message);
|
|
||||||
sodium_memzero($key);
|
|
||||||
return $cipher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt a message
|
|
||||||
*
|
|
||||||
* @param string $encrypted Message encrypted with safeEncrypt()
|
|
||||||
* @param string $key Encryption key (as hex string)
|
|
||||||
* @return string
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public static function decrypt(string $encrypted, string $key): string
|
|
||||||
{
|
|
||||||
$key = self::createKey($key);
|
|
||||||
$decoded = base64_decode($encrypted);
|
$decoded = base64_decode($encrypted);
|
||||||
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||||
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||||
@@ -93,7 +109,7 @@ class SymmetricEncryption
|
|||||||
$key
|
$key
|
||||||
);
|
);
|
||||||
} catch (SodiumException $e) {
|
} catch (SodiumException $e) {
|
||||||
throw new \UnexpectedValueException('Invalid ciphertext (too short)');
|
throw new \UnexpectedValueException('Decipher message failed: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
if (!is_string($plain)) {
|
if (!is_string($plain)) {
|
||||||
throw new \UnexpectedValueException('Invalid Key');
|
throw new \UnexpectedValueException('Invalid Key');
|
||||||
@@ -102,6 +118,117 @@ class SymmetricEncryption
|
|||||||
sodium_memzero($key);
|
sodium_memzero($key);
|
||||||
return $plain;
|
return $plain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a message
|
||||||
|
*
|
||||||
|
* @param string $message Message to encrypt
|
||||||
|
* @param ?string $key Mandatory encryption key, will throw exception if empty
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \RangeException
|
||||||
|
*/
|
||||||
|
private function encryptData(string $message, ?string $key): string
|
||||||
|
{
|
||||||
|
if (empty($this->key) || $key === null) {
|
||||||
|
throw new \UnexpectedValueException('Key not set');
|
||||||
|
}
|
||||||
|
$key = $this->createKey($key);
|
||||||
|
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||||
|
try {
|
||||||
|
$cipher = base64_encode(
|
||||||
|
$nonce
|
||||||
|
. sodium_crypto_secretbox(
|
||||||
|
$message,
|
||||||
|
$nonce,
|
||||||
|
$key,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (SodiumException $e) {
|
||||||
|
throw new \UnexpectedValueException("Create encrypted message failed: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
sodium_memzero($message);
|
||||||
|
sodium_memzero($key);
|
||||||
|
return $cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************
|
||||||
|
* MARK: PUBLIC
|
||||||
|
* *************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set a new key for encryption
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setKey(string $key)
|
||||||
|
{
|
||||||
|
if (empty($key)) {
|
||||||
|
throw new \UnexpectedValueException('Key cannot be empty');
|
||||||
|
}
|
||||||
|
$this->key = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a message
|
||||||
|
* static version
|
||||||
|
*
|
||||||
|
* @param string $encrypted Message encrypted with safeEncrypt()
|
||||||
|
* @param string $key Encryption key (as hex string)
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \RangeException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
*/
|
||||||
|
public static function decryptKey(string $encrypted, string $key): string
|
||||||
|
{
|
||||||
|
return self::getInstance()->decryptData($encrypted, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a message
|
||||||
|
*
|
||||||
|
* @param string $encrypted Message encrypted with safeEncrypt()
|
||||||
|
* @return string
|
||||||
|
* @throws \RangeException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
*/
|
||||||
|
public function decrypt(string $encrypted): string
|
||||||
|
{
|
||||||
|
return $this->decryptData($encrypted, $this->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a message
|
||||||
|
* static version
|
||||||
|
*
|
||||||
|
* @param string $message Message to encrypt
|
||||||
|
* @param string $key Encryption key (as hex string)
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \RangeException
|
||||||
|
*/
|
||||||
|
public static function encryptKey(string $message, string $key): string
|
||||||
|
{
|
||||||
|
return self::getInstance()->encryptData($message, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a message
|
||||||
|
*
|
||||||
|
* @param string $message Message to encrypt
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \RangeException
|
||||||
|
*/
|
||||||
|
public function encrypt(string $message): string
|
||||||
|
{
|
||||||
|
return $this->encryptData($message, $this->key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
|
|||||||
Reference in New Issue
Block a user