Skip to content

Instantly share code, notes, and snippets.

@pritdeveloper
Last active June 3, 2025 08:32
Show Gist options
  • Select an option

  • Save pritdeveloper/6c1b3ba4770731fc48fb6fbd329b1430 to your computer and use it in GitHub Desktop.

Select an option

Save pritdeveloper/6c1b3ba4770731fc48fb6fbd329b1430 to your computer and use it in GitHub Desktop.
if (!function_exists('pr')) {
function pr()
{
foreach (func_get_args() as $e) {
echo "<pre>";
print_r($e);
echo "</pre>";
}
}
}
if (!function_exists('vd')) {
function vd()
{
foreach (func_get_args() as $e) {
echo "<pre>";
var_dump($e);
echo "</pre>";
}
}
}
if (!function_exists('jl')) {
function jl($e, $loc = __DIR__, $file_name = '', $raw_log = false)
{
$bt = debug_backtrace();
$found_trace = false;
while (!empty($bt)) {
$trace = array_shift($bt);
if (isset($trace['function']) && 'lg' == $trace['function']) {
$found_trace = true;
break;
}
}
$raw_log = true === $raw_log;
if ($loc && !is_dir($loc)) $loc = __DIR__;
if (!$file_name) {
$file_name = 'log' . (!$raw_log ? '.json' : '');
}
if (!$loc || true === $found_trace) {
$overwrite_file_name = !!$loc;
$file_path = $trace['file'];
$pathinfo = pathinfo($file_path);
$loc = $pathinfo['dirname'];
if (true === $overwrite_file_name) {
$file_name = $pathinfo['basename'] . ".log";
}
}
$log_data = $raw_log ? print_r($e, true) : @json_encode($e, JSON_PRETTY_PRINT);
@error_log($log_data . "\n\n", 3, $loc . "/{$file_name}");
}
}
if (!function_exists('lg')) {
function lg($e, string $filename = '')
{
jl($e, !empty($filename) ? '' : __DIR__, $filename, true);
}
}
if (!function_exists('db')) {
function db($return = false)
{
$e = debug_backtrace();
if (true === $return) {
return $e;
}
foreach (
array(
'r',
'pr',
'vd'
) as $func
) {
if (function_exists($func)) {
$func($e);
return;
}
}
echo '<pre>';
print_r($e);
echo '</pre>';
}
}
if (!function_exists('env')) {
function env($key, $default = null)
{
$value = getenv($key);
if ($value === false) {
return $default;
}
return $value;
}
}
if (!function_exists('osed')) {
function osed($data, bool | string $decr = false, string | null $secret = null)
{
$data = osed_serialize($data); // serialize data to be sure it is a string
if (is_string($decr)) {
$secret = $decr;
$decr = false;
}
if (!(function_exists('openssl_encrypt') && function_exists('hash'))) {
if (true === $decr) {
return base64_decode($data);
}
return base64_encode($data);
}
$method = 'AES-256-CBC';
$iv_length = openssl_cipher_iv_length($method);
if (!$secret) $secret = '_osed_secret_key';
// hash the secret key
$secret = hash('sha256', $secret, true);
if (true === $decr) {
$data = base64_decode(strtr($data, '-_', '+/'));
$iv = substr($data, $iv_length, $iv_length);
$data = substr($data, $iv_length * 2, -$iv_length);
$output = openssl_decrypt($data, $method, $secret, OPENSSL_RAW_DATA, $iv);
$output = osed_unserialize($output); // unserialize data to match the original data
} else {
$iv = openssl_random_pseudo_bytes($iv_length);
$encrypted = openssl_encrypt($data, $method, $secret, OPENSSL_RAW_DATA, $iv);
if (false === $encrypted) {
return false;
}
$package = openssl_random_pseudo_bytes($iv_length) . $iv . $encrypted . openssl_random_pseudo_bytes($iv_length);
$output = rtrim(strtr(base64_encode($package), '+/', '-_'), '=');
}
return $output;
}
function osed_serialize($data)
{
if (is_array($data) || is_object($data)) {
return serialize($data);
}
return $data;
}
function osed_unserialize($data)
{
if (osed_is_serialized($data)) {
$data = unserialize($data);
}
return $data;
}
function osed_is_serialized($data)
{
if (is_string($data)) {
$data = trim($data);
if ('N;' == $data) {
return true;
}
if (strlen($data) < 4) {
return false;
}
if ('s:' == substr($data, 0, 2)) {
return false !== strpos($data, ':');
}
if ('a:' == substr($data, 0, 2)) {
return false !== strpos($data, ':');
}
if ('O:' == substr($data, 0, 2)) {
return false !== strpos($data, ':');
}
}
return false;
}
}
if (!function_exists('soed')) {
function soed($data, string $secret, bool $decrypt = false)
{
// --- Dependency Checks ---
// Check if Sodium is available
if (!extension_loaded('sodium')) {
throw new RuntimeException('Sodium extension is required but not enabled.');
}
// Check if the hash functions are available (hash_pbkdf2 and hash_hmac)
if (!function_exists('hash_pbkdf2') || !function_exists('hash_hmac')) {
throw new RuntimeException('The hash functions (hash_pbkdf2 or hash_hmac) are required but not available.');
}
// Check if the JSON extension is available
if (!extension_loaded('json')) {
throw new RuntimeException('The JSON extension is required but not enabled.');
}
// Check if base64 functions are available
if (!function_exists('base64_encode') || !function_exists('base64_decode')) {
throw new RuntimeException('Base64 encoding/decoding functions are required but not available.');
}
// --- Encryption/Decryption Logic ---
$key_length = 32; // 256-bit key length
$salt_length = 16; // 128-bit salt
$iterations = 100_000; // PBKDF2 iterations
$iv_length = SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES; // 12 bytes for nonce
if (!$decrypt) {
// --- ENCRYPTION (v2) ---
$version = 'v2';
$iv = random_bytes($iv_length); // Secure nonce (random)
$salt = random_bytes($salt_length); // Random salt
$key = hash_pbkdf2('sha256', $secret, $salt, $iterations, $key_length, true); // Derive encryption key from password
// Encrypt the data
$ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
json_encode($data, JSON_THROW_ON_ERROR), // The plaintext data
'', // No associated data
$iv, // The nonce (IV)
$key // The derived key
);
// Construct the payload
$payload = [
'version' => $version,
'iv' => soed_base64_encode($iv),
'salt' => soed_base64_encode($salt),
'ciphertext' => soed_base64_encode($ciphertext),
];
// Add HMAC for integrity check (MAC over payload)
$mac = hash_hmac('sha256', json_encode($payload, JSON_THROW_ON_ERROR), $secret, true);
$payload['mac'] = soed_base64_encode($mac);
// Return the final base64-encoded and JSON-encoded payload
return soed_base64_encode(json_encode($payload, JSON_THROW_ON_ERROR));
} else {
// --- DECRYPTION ---
$decoded = soed_base64_decode($data, true);
if ($decoded === false) {
throw new InvalidArgumentException('Base64 decoding failed.');
}
// Try to parse as JSON payload (v2)
$payload = json_decode($decoded, true);
if (is_array($payload) && isset($payload['version']) && $payload['version'] === 'v2') {
// Validate required keys and HMAC
foreach (['iv', 'salt', 'ciphertext', 'mac'] as $key) {
if (empty($payload[$key])) {
throw new InvalidArgumentException("Missing $key in encrypted data.");
}
}
// Validate the HMAC first
$expected_mac = soed_base64_decode($payload['mac'], true);
if ($expected_mac === false) {
throw new InvalidArgumentException('Invalid MAC format.');
}
unset($payload['mac']); // Remove MAC to compute our own
$computed_mac = hash_hmac('sha256', json_encode($payload, JSON_THROW_ON_ERROR), $secret, true);
if (!hash_equals($computed_mac, $expected_mac)) {
throw new RuntimeException('MAC verification failed. Data integrity compromised.');
}
// Decode components
$iv = soed_base64_decode($payload['iv'], true);
$salt = soed_base64_decode($payload['salt'], true);
$ciphertext = soed_base64_decode($payload['ciphertext'], true);
if (!$iv || !$salt || !$ciphertext) {
throw new InvalidArgumentException('Failed to decode components.');
}
$key = hash_pbkdf2('sha256', $secret, $salt, $iterations, $key_length, true);
// Decrypt the data
$plaintext = sodium_crypto_aead_aes256gcm_decrypt(
$ciphertext, // The encrypted ciphertext
'', // No associated data
$iv, // The nonce (IV)
$key // The derived key
);
if ($plaintext === false) {
throw new RuntimeException('Decryption failed or data was tampered with.');
}
return json_decode($plaintext, true, 512, JSON_THROW_ON_ERROR);
} else {
throw new InvalidArgumentException('Invalid or unsupported encryption format.');
}
}
}
function soed_base64_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function soed_base64_decode($data)
{
$decoded = base64_decode(strtr($data, '-_', '+/'), true);
if ($decoded === false) {
throw new InvalidArgumentException('Base64 decoding failed.');
}
return $decoded;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment