Compare commits

..

6 Commits

Author SHA1 Message Date
Clemens Schwaighofer 770d6f30a4 DB\IO Placeholder regex fix for json queries, test data updates
Some doc typo fixes
test updates with remove of not used sub calls

DB IO Placeholder regex now checks for any JSON/JSONB operators
2024-07-29 15:55:38 +09:00
Clemens Schwaighofer f94f6cbe87 Add .shellcheckrc, move phpstan tmp folder to repository temp folder 2024-07-19 18:40:24 +09:00
Clemens Schwaighofer 9b69390fa2 Merge branch 'development' into NewFeatures 2024-05-22 10:47:12 +09:00
Clemens Schwaighofer 0524d8ac1b Update Symmetric Encryption
Can be used as a class with central key set.

for old static calls:
encrypt -> encryptKey
decrypt -> decryptKey
2024-05-22 10:43:54 +09:00
Clemens Schwaighofer e933022671 Phive update 2024-05-22 10:27:20 +09:00
Clemens Schwaighofer c549d34e65 phive tools update 2024-05-15 17:06:09 +09:00
21 changed files with 308 additions and 94 deletions
+5 -5
View File
@@ -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>
+2
View File
@@ -0,0 +1,2 @@
shell=bash
external-sources=true
+2 -2
View File
@@ -12,7 +12,7 @@ if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
opt_testdox="--testdox"; opt_testdox="--testdox";
fi; fi;
php_bin=""; php_bin="";
if [ ! -z "${1}" ]; then if [ -n "${1}" ]; then
case "${1}" in case "${1}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;; # "7.3") php_bin="/usr/bin/php7.3 "; ;;
# "7.4") php_bin="/usr/bin/php7.4 "; ;; # "7.4") php_bin="/usr/bin/php7.4 "; ;;
@@ -23,7 +23,7 @@ if [ ! -z "${1}" ]; then
*) echo "Not support PHP: ${1}"; exit; ;; *) echo "Not support PHP: ${1}"; exit; ;;
esac; esac;
fi; fi;
if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then if [ -n "${2}" ] && [ -z "${php_bin}" ]; then
case "${2}" in case "${2}" in
# "7.3") php_bin="/usr/bin/php7.3 "; ;; # "7.3") php_bin="/usr/bin/php7.3 "; ;;
# "7.4") php_bin="/usr/bin/php7.4 "; ;; # "7.4") php_bin="/usr/bin/php7.4 "; ;;
@@ -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
View File
@@ -2,7 +2,7 @@
includes: includes:
- phpstan-conditional.php - phpstan-conditional.php
parameters: parameters:
tmpDir: /tmp/phpstan-corelibs tmpDir: %currentWorkingDirectory%/tmp/phpstan-corelibs
level: 8 # max is now 9 level: 8 # max is now 9
checkMissingCallableSignature: true checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+1 -1
View File
@@ -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
View File
@@ -1 +1 @@
/home/clemens/.phive/phars/phpcbf-3.9.1.phar /home/clemens/.phive/phars/phpcbf-3.10.0.phar
+1 -1
View File
@@ -1 +1 @@
/home/clemens/.phive/phars/phpcs-3.9.1.phar /home/clemens/.phive/phars/phpcs-3.10.0.phar
+1 -1
View File
@@ -1 +1 @@
/home/clemens/.phive/phars/phpstan-1.10.67.phar /home/clemens/.phive/phars/phpstan-1.11.1.phar
+1 -1
View File
@@ -1 +1 @@
/home/clemens/.phive/phars/psalm-5.23.1.phar /home/clemens/.phive/phars/psalm-5.24.0.phar
+1 -1
View File
@@ -21,7 +21,7 @@ ob_end_flush();
use CoreLibs\Combined\ArrayHandler; use CoreLibs\Combined\ArrayHandler;
use CoreLibs\Debug\Support as DgS; use CoreLibs\Debug\Support as DgS;
use CoreLibs\Convert\SetVarType; use CoreLibs\Convert\SetVarType;
use PHPUnit\Framework\Constraint\ArrayHasKey; // use PHPUnit\Framework\Constraint\ArrayHasKey;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
+1
View File
@@ -451,6 +451,7 @@ function intervalStringFormatDeprecated(
$value = $interval->days; $value = $interval->days;
$skip = true; $skip = true;
} else { } else {
/** @phan-suppress-next-line PhanUndeclaredProperty */
$value = $interval->$part; $value = $interval->$part;
} }
if ($value == 0 && $skip_last_zero === true) { if ($value == 0 && $skip_last_zero === true) {
@@ -20,7 +20,7 @@ $LOG_FILE_ID = 'classTest-db-query-placeholder';
ob_end_flush(); ob_end_flush();
use CoreLibs\Debug\Support; use CoreLibs\Debug\Support;
use CoreLibs\DB\Support\ConvertPlaceholder; // use CoreLibs\DB\Support\ConvertPlaceholder;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
+1 -1
View File
@@ -19,7 +19,7 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-db-query-placeholders'; $LOG_FILE_ID = 'classTest-db-query-placeholders';
ob_end_flush(); ob_end_flush();
use CoreLibs\Debug\Support; // use CoreLibs\Debug\Support;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
+27 -21
View File
@@ -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>";
} }
+1 -1
View File
@@ -97,7 +97,7 @@ $smarty->DATA['drop_down_test'] = [
'foobar' => 'Foo Bar', 'foobar' => 'Foo Bar',
]; ];
$smarty->DATA['drop_down_test_selected'] = 'bar'; $smarty->DATA['drop_down_test_selected'] = 'bar';
$smarty->DATA['drop_down_test_nested'] = [ $smarty->DATA['drop_down_test_nested'] = [
'' => '選択してください', '' => '選択してください',
'4/25(木)' => [ '4/25(木)' => [
'4/25(木) 11:00-11:50' => '4/25(木) 11:00-11:50', '4/25(木) 11:00-11:50' => '4/25(木) 11:00-11:50',
@@ -39,9 +39,11 @@ class ConvertPlaceholder
): array { ): array {
$convert_to = strtolower($convert_to); $convert_to = strtolower($convert_to);
$matches = []; $matches = [];
$query_split = '[(=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-';
$pattern = '/' $pattern = '/'
// prefix string part, must match towards // prefix string part, must match towards
. '(?:\'.*?\')?\s*(?:\?\?|[(=,])\s*' // seperator for ( = , ? - [and json/jsonb in pg doc section 9.15]
. '(?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*'
// match for replace part // match for replace part
. '(?:' . '(?:'
// digit -> ignore // digit -> ignore
@@ -96,7 +98,10 @@ class ConvertPlaceholder
$type = 'named'; $type = 'named';
$matches_return = $named_matches; $matches_return = $named_matches;
// only check for :named // only check for :named
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(:\w+))/s'; $pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(:\w+))'
. '/s';
// 0: full // 0: full
// 1: pre part // 1: pre part
// 2: keep part UNLESS '3' is set // 2: keep part UNLESS '3' is set
@@ -134,7 +139,10 @@ class ConvertPlaceholder
// order and data stays the same // order and data stays the same
$params_new = $params; $params_new = $params;
// only check for ? // only check for ?
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))/s'; $pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(?:(?:\?\?)?\s*(\?{1})))'
. '/s';
// 0: full // 0: full
// 1: pre part // 1: pre part
// 2: keep part UNLESS '3' is set // 2: keep part UNLESS '3' is set
@@ -163,7 +171,10 @@ class ConvertPlaceholder
$type = 'numbered'; $type = 'numbered';
$matches_return = $numbered_matches; $matches_return = $numbered_matches;
// only check for $n // only check for $n
$pattern_replace = '/((?:\'.*?\')?\s*(?:\?\?|[(=,])\s*)(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))/s'; $pattern_replace = '/'
. '((?:\'.*?\')?\s*(?:\?\?|' . $query_split . ')\s*)'
. '(\d+|(?:\'.*?\')|(\$[1-9]{1}(?:[0-9]{1,})?))'
. '/s';
// 0: full // 0: full
// 1: pre part // 1: pre part
// 2: keep part UNLESS '3' is set // 2: keep part UNLESS '3' is set
@@ -46,7 +46,7 @@ class CachedFileReader extends \CoreLibs\Language\Core\StringReader
if (!is_resource($fd)) { if (!is_resource($fd)) {
$this->error = 3; // Cannot read file, probably permissions $this->error = 3; // Cannot read file, probably permissions
} else { } else {
$this->fd_str = fread($fd, filesize($filename) ?: 0) ?: ''; $this->fd_str = fread($fd, filesize($filename) ?: 1) ?: '';
fclose($fd); fclose($fd);
} }
} else { } else {
+164 -37
View File
@@ -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__
+1 -1
View File
@@ -185,7 +185,7 @@ class SmartyExtend extends \Smarty
// call basic smarty // call basic smarty
// or Smarty::__construct(); // or Smarty::__construct();
parent::__construct(); parent::__construct();
// iinit lang // init lang
$this->l10n = $l10n; $this->l10n = $l10n;
// parse and read, legacy stuff // parse and read, legacy stuff
$locale = $this->l10n->getLocaleAsArray(); $locale = $this->l10n->getLocaleAsArray();