CoreLibs add Security\SymmetricEncryption

This commit is contained in:
2023-05-24 16:00:49 +09:00
parent b16ff4c613
commit c010673705
9 changed files with 424 additions and 25 deletions

View File

@@ -0,0 +1,61 @@
<?php
/**
* very simple symmetric encryption
* better use: https://paragonie.com/project/halite
*
* this is for creating secret keys for
* Security\SymmetricEncryption
*/
declare(strict_types=1);
namespace CoreLibs\Security;
class CreateKey
{
/**
* Create a random key that is a hex string
*
* @return string Hex string key for encrypting
*/
public static function generateRandomKey(): string
{
return self::bin2hex(self::randomKey());
}
/**
* create a random string as binary to encrypt data
* to store it in clear text in some .env file use bin2hex
*
* @return string Binary string for encryption
*/
public static function randomKey(): string
{
return random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
}
/**
* convert binary key to hex string
*
* @param string $hex_key Convert binary key string to hex
* @return string
*/
public static function bin2hex(string $hex_key): string
{
return sodium_bin2hex($hex_key);
}
/**
* convert hex string to binary key
*
* @param string $string_key Convery hex key string to binary
* @return string
*/
public static function hex2bin(string $string_key): string
{
return sodium_hex2bin($string_key);
}
}
// __END__

59
src/Security/Password.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
/*
* core password set, check and rehash check wrapper functions
*/
declare(strict_types=1);
namespace CoreLibs\Security;
class Password
{
/**
* creates the password hash
*
* @param string $password password
* @return string hashed password
*/
public static function passwordSet(string $password): string
{
// always use the PHP default for the password
// password options ca be set in the password init,
// but should be kept as default
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* checks if the entered password matches the hash
*
* @param string $password password
* @param string $hash password hash
* @return bool true or false
*/
public static function passwordVerify(string $password, string $hash): bool
{
if (password_verify($password, $hash)) {
return true;
} else {
return false;
}
}
/**
* checks if the password needs to be rehashed
*
* @param string $hash password hash
* @return bool true or false
*/
public static function passwordRehashCheck(string $hash): bool
{
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
return true;
} else {
return false;
}
}
}
// __END__

View File

@@ -0,0 +1,96 @@
<?php
/**
* very simple symmetric encryption
* Better use: https://paragonie.com/project/halite
*
* current code is just to encrypt and decrypt
*
* must use a valid encryption key created with
* Secruty\CreateKey class
*/
declare(strict_types=1);
namespace CoreLibs\Security;
use CoreLibs\Security\CreateKey;
use SodiumException;
class SymmetricEncryption
{
/**
* Encrypt a message
*
* @param string $message Message to encrypt
* @param string $key Encryption key (as hex string)
* @return string
* @throws \RangeException
*/
public static function encrypt(string $message, string $key): string
{
try {
$key = CreateKey::hex2bin($key);
} catch (SodiumException $e) {
throw new \Exception('Invalid hex key');
}
if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
throw new \RangeException(
'Key is not the correct size (must be '
. 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
);
}
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$cipher = base64_encode(
$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
{
try {
$key = CreateKey::hex2bin($key);
} catch (SodiumException $e) {
throw new \Exception('Invalid hex key');
}
$decoded = base64_decode($encrypted);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$plain = false;
try {
$plain = sodium_crypto_secretbox_open(
$ciphertext,
$nonce,
$key
);
} catch (SodiumException $e) {
throw new \Exception('Invalid ciphertext (too short)');
}
if (!is_string($plain)) {
throw new \Exception('Invalid Key');
}
sodium_memzero($ciphertext);
sodium_memzero($key);
return $plain;
}
}
// __END__