* @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. * @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(); writeFile($file_name, $key); chmodFileOrDir($file_name, getPerms("secret")); changeOwner($file_name, "root", "root"); } else { $key = readMyFile($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; } }