I am planning to encrypt database fields using AES encryption. Now, this encrypted data will not transfer over the internet and will reside in our own datacenter only.
From what I read, GCM mode should be the obvious choice for encryption since it's more secure(basically it's authentication encryption) and it's fast.
But do I need to use authentication encryption in this case? I mean data will reside inside our servers only. So can I use CBC mode without appending MAC to encrypted text. I want to use CBC since we are using PHP 5.6 in prod(for some legacy code, I know this version of PHP should not be used in prod any how). Or do I need to first encrypt using CBC mode and then calculate MAC for encrypted text and then hash it and append to cipher?
So, will CBC solve my purpose. I have written this code?
Is this secure or not
function encrypt($key, $textToEncrypt){
$cipher = AES_256_CBC;
$iv_len = 16;
$version_length = 3;
$version = "v01";
$iv = openssl_random_pseudo_bytes($iv_len);
$ciphertext = openssl_encrypt($textToEncrypt, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext, $key, $as_binary=true);
$encrypted = base64_encode($version.$iv.$hmac.$ciphertext);
return $encrypted;
}
function decrypt($key, $textToDecrypt){
$cipher = AES_256_CBC;
$iv_len = 16;
$version_length = 3;
$encrypted = base64_decode($textToDecrypt);
$version = substr($encrypted, 0, $version_length);
$iv = substr($encrypted, $version_length , $iv_len);
$hmac = substr($encrypted, $version_length + $iv_len, $sha2len=32);
$ciphertext = substr($encrypted, $iv_len + $version_length + $sha2len );
$decrypted = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
{
echo $decrypted."\n";
}
return "";
}