<?php
if (!defined("BASEPATH")) { exit("No direct script access allowed"); }

class UnilaSecure
{
    // =================== Encrypt for server side ====================
    
    function encrypt($data) { 
        // Get config key from security.ini
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $security['key'], false), 0, 32);
        
        // Encrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = openssl_random_pseudo_bytes($iv_len);
        $tag = "";

        $ciphertext = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, "", $tag_length);
        $encrypted = strtr(rtrim(base64_encode($iv.$ciphertext.$tag), '='), '+/', '-_');
        
        return $encrypted;
    }

    function decrypt($data) {        
        // Decode encrypted data
        $encrypted = base64_decode(strtr(str_pad($data, ceil(strlen($data) / 4) * 4, '=', STR_PAD_RIGHT), '-_', '+/'));
        
        // Get config key from security.ini
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $security['key'], false), 0, 32);
        
        // Decrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = substr($encrypted, 0, $iv_len);
        $ciphertext = substr($encrypted, $iv_len, -$tag_length);
        $tag = substr($encrypted, -$tag_length);

        $decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        
        return $decrypted;
    }
    
    function encrypt_arr($data) { 
        // Serialize array and hashing client key
        $security = parse_ini_file('UnilaSecure.ini');
        $textToEncrypt = serialize($data);
        $key = substr(hash($security['hash'], $security['key'], false), 0, 32);
        
        // Encrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = openssl_random_pseudo_bytes($iv_len);
        $tag = "";

        $ciphertext = openssl_encrypt($textToEncrypt, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, "", $tag_length);
        $encrypted = strtr(rtrim(base64_encode($iv.$ciphertext.$tag), '='), '+/', '-_');
        
        return $encrypted;
    }

    function decrypt_arr($data) {        
        // Serialize array and hashing client key
        $encrypted = base64_decode(strtr(str_pad($data, ceil(strlen($data) / 4) * 4, '=', STR_PAD_RIGHT), '-_', '+/'));
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $security['key'], false), 0, 32);
        
        // Decrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = substr($encrypted, 0, $iv_len);
        $ciphertext = substr($encrypted, $iv_len, -$tag_length);
        $tag = substr($encrypted, -$tag_length);

        $decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        
        return unserialize($decrypted);
    }
    
    // =================== End of Encrypt for server side ====================
    
    // =================== Encrypt for client-server side ====================
    
    function encrypt_client($data, $client_key) { 
        // Serialize array and hashing client key
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $client_key, false), 0, 32);
        
        // Encrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = openssl_random_pseudo_bytes($iv_len);
        $tag = "";

        $ciphertext = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, "", $tag_length);
        $encrypted = strtr(rtrim(base64_encode($iv.$ciphertext.$tag), '='), '+/', '-_');
        
        return $encrypted;
    }

    function decrypt_client($data, $client_key) {        
        // Serialize array and hashing client key
        $encrypted = base64_decode(strtr(str_pad($data, ceil(strlen($data) / 4) * 4, '=', STR_PAD_RIGHT), '-_', '+/'));
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $client_key, false), 0, 32);
        
        // Decrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = substr($encrypted, 0, $iv_len);
        $ciphertext = substr($encrypted, $iv_len, -$tag_length);
        $tag = substr($encrypted, -$tag_length);

        $decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        
        return $decrypted;
    }
    
    function encrypt_client_arr($data, $client_key) { 
        // Serialize array and hashing client key
        $security = parse_ini_file('UnilaSecure.ini');
        $textToEncrypt = serialize($data);
        $key = substr(hash($security['hash'], $client_key, false), 0, 32);
        
        // Encrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = openssl_random_pseudo_bytes($iv_len);
        $tag = "";

        $ciphertext = openssl_encrypt($textToEncrypt, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag, "", $tag_length);
        $encrypted = strtr(rtrim(base64_encode($iv.$ciphertext.$tag), '='), '+/', '-_');
        
        return $encrypted;
    }

    function decrypt_client_arr($data, $client_key) {        
        // Serialize array and hashing client key
        $encrypted = base64_decode(strtr(str_pad($data, ceil(strlen($data) / 4) * 4, '=', STR_PAD_RIGHT), '-_', '+/'));
        $security = parse_ini_file('UnilaSecure.ini');
        $key = substr(hash($security['hash'], $client_key, false), 0, 32);
        
        // Decrypt using AES-256-GCM algorithm
        $cipher = $security['method'];
        $iv_len = openssl_cipher_iv_length($cipher);
        $tag_length = 16;
        $iv = substr($encrypted, 0, $iv_len);
        $ciphertext = substr($encrypted, $iv_len, -$tag_length);
        $tag = substr($encrypted, -$tag_length);

        $decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        
        return unserialize($decrypted);
    }
    
    // =================== End of Encrypt for client-server side ====================
}