I'm writing a symmetric encryption scheme for a product that I'm working on which doesn't store sensitive data (license validation data). I'd still rather do it right and reuse it than do it wrong and make something useless.
I have some concerns about HMAC after encrypting and making sure that the HMAC actually serves its purpose. I read this article on avoiding mcrypt
vs OpenSSL which pretty adamently promotes the concept of MAC-after-encryption.
Now here is my current process for encrypting the data (you can imagine how the decryption side works):
//PHP7
function encrypt($message, $key){
$method = 'aes-256-cbc';
if (mb_strlen($key, '8bit') !== 32) {
throw new Exception("Needs a 256-bit key");
}
$ivsize = openssl_cipher_iv_length($method);
$iv = random_bytes($ivsize);
$ciphertext = openssl_encrypt(
$message,
$method,
$key,
OPENSSL_RAW_DATA,
$iv
);
$hmac = hash_hmac('sha256', $iv . $ciphertext, $iv, true);
return base64_encode($hmac . $iv . $ciphertext);
}
My concern is that the HMAC key is the same as the IV which is prepended to the data stream. In theory, anybody attempting to break this can figure out that the first 32 bytes are the HMAC, the second 16 bytes are the IV, and the rest is the cipher text, since it seems to be an industry standard. Somebody running a Vaudenay Attack could potentially modify the cipher text and regenerate the HMAC easily using the IV.
So would it be more secure to use the AES key for the HMAC since that is not passed or stored? Or maybe something different like the XOR
of the AES key and the IV? Or a completely new key using another round of random_bytes()
?
Should the MAC key be treated just like the AES key in terms of secrecy?
This post titled "Why Can't I use the same key for encryption and MAC" suggests that it is not appropriate to do for AES-CBC mode, lets assume that AES-CBC-MAC is not available to me (because the decryption side is a different library and language).