You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.9 KiB
217 lines
5.9 KiB
<?php
|
|
/**
|
|
* Crypto - Encryption
|
|
*
|
|
* PHP version 8.3
|
|
*
|
|
* @category Util
|
|
* @package Neato
|
|
* @author Robert S. <tips@technowizardbob.com>
|
|
* @license https://mit-license.org/ MIT License
|
|
* @link https://git.mysnippetsofcode.com/tts/neatoDeploy
|
|
*/
|
|
|
|
/**
|
|
* Encode and Decode secrets
|
|
*
|
|
* @category Util
|
|
* @package Neato
|
|
* @author Robert S. <tips@technowizardbob.com>
|
|
* @license https://mit-license.org/ MIT License
|
|
* @link https://git.mysnippetsofcode.com/tts/neatoDeploy
|
|
*/
|
|
class Enc
|
|
{
|
|
|
|
/**
|
|
* SafeEncrypt make communications private
|
|
*
|
|
* @param string $message to encode
|
|
* @param string $my_key encode with a secret key
|
|
*
|
|
* @return string cipher text data
|
|
*/
|
|
public static function safeEncrypt(string $message, string $my_key = "")
|
|
{
|
|
$nonce = "";
|
|
$cipher = "";
|
|
|
|
$my_key = hex2bin($my_key);
|
|
|
|
$nonce = random_bytes(
|
|
SODIUM_CRYPTO_SECRETBOX_NONCEBYTES
|
|
);
|
|
|
|
$cipher = base64_encode(
|
|
$nonce .
|
|
sodium_crypto_secretbox(
|
|
$message,
|
|
$nonce,
|
|
$my_key
|
|
)
|
|
);
|
|
sodium_memzero($message);
|
|
sodium_memzero($my_key);
|
|
return $cipher;
|
|
}
|
|
|
|
/**
|
|
* Decode secret message into plan text
|
|
*
|
|
* @param string $encrypted your cypher text
|
|
* @param string $my_key secret key used by enc...
|
|
*
|
|
* @return string of plan text message
|
|
*
|
|
* @throws \Exception
|
|
*/
|
|
public static function safeDecrypt(string $encrypted, string $my_key = ""): string
|
|
{
|
|
$decoded = "";
|
|
$nonce = "";
|
|
$ciphertext = "";
|
|
$plain = "";
|
|
|
|
$my_key = hex2bin($my_key);
|
|
|
|
/**
|
|
* Use decoded and check if valid.
|
|
*
|
|
* @param false|string $decoded did it base64_code?
|
|
* base64_decode may return a false!!!
|
|
* Ignore the error in phpstan!! It is all correct here:
|
|
*/
|
|
$decoded = base64_decode($encrypted);
|
|
// @phpstan-ignore-next-line
|
|
if ($decoded === false) {
|
|
throw new \Exception("The encoding failed!");
|
|
}
|
|
if (mb_strlen($decoded, "8bit") < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
|
|
throw new \Exception("The message was truncated!");
|
|
}
|
|
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, "8bit");
|
|
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, "8bit");
|
|
|
|
$plain = sodium_crypto_secretbox_open(
|
|
$ciphertext,
|
|
$nonce,
|
|
$my_key
|
|
);
|
|
if ($plain === false) {
|
|
throw new \Exception("The message was tampered with in transit!");
|
|
}
|
|
sodium_memzero($ciphertext);
|
|
sodium_memzero($my_key);
|
|
return $plain;
|
|
}
|
|
|
|
/**
|
|
* Create and Save a good key for secrets later on...
|
|
*
|
|
* @param string $file_name save to this file
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function makeKeyFile(string $file_name): string
|
|
{
|
|
if (!file_exists($file_name)) {
|
|
$key = self::generateKey();
|
|
write_file($file_name, $key);
|
|
chmod_file_or_dir($file_name, getPerms("secret"));
|
|
change_owner($file_name, "root", "root");
|
|
} else {
|
|
$key = read_file($file_name);
|
|
}
|
|
return $key;
|
|
}
|
|
|
|
/**
|
|
* Gereate a Good strong Key
|
|
*
|
|
* @return string New Random Key for secure crypto
|
|
*/
|
|
public static function generateKey(): string
|
|
{
|
|
return bin2hex(random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES));
|
|
}
|
|
|
|
/**
|
|
* Lets recover the secret stuff from a file.
|
|
*
|
|
* @param string $file_name Read crypto junk
|
|
* @param string $key your secret Key
|
|
*
|
|
* @return mixed decrypted data
|
|
*/
|
|
public static function decodeFile(string $file_name, string $key)
|
|
{
|
|
$ciphertext = file_get_contents($file_name);
|
|
$ret = json_decode(base64_decode(self::safeDecrypt(self::_binToHexToString($ciphertext), $key)), false);
|
|
sodium_memzero($ciphertext);
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* EncodeFile writes to file and srambles the data
|
|
*
|
|
* @param string $file_name Write to this file
|
|
* @param mixed $data My message to encode
|
|
* @param string $key your secret Key
|
|
*
|
|
* @return void not ah
|
|
*/
|
|
public static function encodeFile(string $file_name, mixed $data, string $key): void
|
|
{
|
|
file_put_contents($file_name, self::_stringToHexToBin(self::safeEncrypt(base64_encode(json_encode((object) $data)), $key)));
|
|
}
|
|
/**
|
|
* Convert a string into hex then into Binary...
|
|
*
|
|
* @param string $str plan text
|
|
*
|
|
* @return string Binary data
|
|
*/
|
|
private static function _stringToHexToBin(string $str): string
|
|
{
|
|
$ooh = 0;
|
|
$hex = "";
|
|
for ($c = 0; $c < strlen($str); $c++) {
|
|
$ch = $str[$c];
|
|
if (ord($ch) + 62 < 255) {
|
|
$ooh = (int) ord($ch) + 62;
|
|
} else {
|
|
$ooh = (int) ord($ch);
|
|
}
|
|
$hex .= hex2bin(dechex($ooh));
|
|
}
|
|
return $hex;
|
|
}
|
|
|
|
/**
|
|
* Convert Binary into Hex into a string again.
|
|
*
|
|
* @param string $hex semi scamble stuff
|
|
*
|
|
* @return string cleaned up stuff again
|
|
*/
|
|
private static function _binToHexToString(string $hex): string
|
|
{
|
|
$decoded = "";
|
|
$my_hex = "";
|
|
$my_dec = "";
|
|
$ooh = 0;
|
|
for ($c = 0; $c < strlen($hex); $c++) {
|
|
$my_bin = $hex[$c];
|
|
$my_hex = bin2hex($my_bin);
|
|
$my_dec = hexdec($my_hex);
|
|
$ooh = (int) ord((string) $my_dec);
|
|
if ($ooh + 62 < 255) {
|
|
$decoded .= chr($my_dec - 62);
|
|
} else {
|
|
$decoded .= chr($my_dec);
|
|
}
|
|
}
|
|
return $decoded;
|
|
}
|
|
|
|
}
|
|
|