2

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 "";
}
1
  • Is it ok to use AE with CBC? Meaning calculate MAC for encrypted text and then appending to cipher and verify it at the time of decryption. – Ankit Bansal Nov 25 '20 at 17:36
3

First of all, your actual risks determined the need for confidentiality, integrity, and authentication. The risks can be deletion of rows, insertion of rows, altering cells, or the rollback of the whole database.. I'll not address these.

You seem only need an authenticated encryption (AE) and not interested in the bundle AES-GCM that provides confidentiality, integrity, and authentication. For the CBC mode of operation, you need HMAC to achieve this. Now your obligations for the CBC mode of operation;

  • choose a uniform random 256-bit key and keep it secret all the time.
  • for each field choose a 128-bit initialization vector (IV) that should be unique and unpredictable
  • The IV can be stored in a column or prepended to the data.
  • the unpredictable requirement of the CBC mode is not a problem in your case.
  • the padding oracle attacks are also not possible in this scenario.
  • the CBC-HMAC must be used as Encrypt-then-MAC

AES-CBC guarantees CPA security. With the AES-CBC-HMAC you will get authenticated encryption.

So, will CBC solve my purpose. I have written this code?

It is not advisable to use the same key for encryption and HMAC, or in short for two different purposes. You can use a Key Derivation function to derive keys for AES and HMAC from the given key HKDF, PBKDF2.

3
  • Note; I've only addressed the CBC part. Addressing the AES-GCM is long and lots of traps. – kelalaka Nov 25 '20 at 18:09
  • Is my code fine? I mean I will use two different keys for hmac and encryption. Rest is it fine. I have already updated the code to remove salt. – Ankit Bansal Nov 25 '20 at 18:15
  • 1
    @AnkitBansal it seems so. You may consider storing all of the generated IV's so that you don't generate the same IV again under the same key. – kelalaka Nov 25 '20 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.