<?php

function encryptData($plaintext, $key = 'gar3')
{

    //$key previously generated safely, ie: openssl_random_pseudo_bytes
    $plaintext = $plaintext;
    $cipher_algo = "AES-256-CBC";
    // $key = $key;
    $options = OPENSSL_RAW_DATA;
    $ivlen = openssl_cipher_iv_length($cipher_algo);
    $iv = openssl_random_pseudo_bytes($ivlen);

    $as_binary = true;

    $ciphertext_raw = openssl_encrypt($plaintext, $cipher_algo, $key, $options, $iv);
    // this create 32 length binary code
    $hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary);
    $ciphertext = base64_encode($iv . $hmac . $ciphertext_raw);

    // echo $ciphertext . "<br>";

    return $ciphertext;
}

function decryptData($ciphertext, $key = 'gar3')
{
    //decrypt later....
    $ciphertext = base64_decode($ciphertext);
    $cipher_algo = "AES-256-CBC";
    // $key = $key;
    $options = OPENSSL_RAW_DATA;
    $ivlen = openssl_cipher_iv_length($cipher_algo);
    $iv = substr($ciphertext, 0, $ivlen);
    $hmac = substr($ciphertext, $ivlen, $sha2len = 32);
    $ciphertext_raw = substr($ciphertext, $ivlen + $sha2len);

    $as_binary = true;

    $plaintext = openssl_decrypt($ciphertext_raw, $cipher_algo, $key, $options, $iv);
    $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary);
    if (hash_equals($hmac, $calcmac)) // timing attack safe comparison
    {
        // echo $plaintext . "<br>";
        return $plaintext;
    }
    return false;
}
