Reputation: 273
I tried implementing encryption in PHP using openssl_encrypt/decrypt. I tried using 128bit AES in GCM mode but then I noticed that even a one byte of the GCM tag is enough for decryption to be successful.
I googled a bit and found this crypto.stackexchange question that encounters the same problem. The issue I am asking again is that this is over a 1 year old and this still doesnt seem to be fixed on the latest versions. I checked this on PHP Version 7.3.9-1 with OpenSSL 1.1.1c 28 May 2019.
$key = 'is_gcm_really_broken_on_php'; //27 bytes ... only need 16 but openssl doesnt use rest automatically. thats ok
$iv = openssl_random_pseudo_bytes(16);
$tag = null;
$toEncrypt = 'hello world';
$encrypted = openssl_encrypt($toEncrypt, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
echo 'tag is ' . strlen($tag) . ' bytes<br>';
$encodedMsg = base64_encode($iv.$tag.$encrypted);
var_dump($encodedMsg);
//.... decrypting
echo '<br><br>decrypting<br>';
$decodedMsg = base64_decode($encodedMsg);
$msgIv = substr($decodedMsg, 0, 16);
$msgTag = substr($decodedMsg, 16, 1);
echo 'using tag thats ' . strlen($msgTag) . ' bytes<br>';
$msgToDecrypt = substr($decodedMsg, 32);
$decrypted = openssl_decrypt($msgToDecrypt, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $msgIv, $msgTag);
echo 'decryption is ok.. no error<br>decrypted message is ' . $decrypted;
Is the code OK and PHP is still insecure in this matter (which is kinda crazy cause there is no warning about it in the documentation)? Or is the code wrong?
Thanks
Upvotes: 1
Views: 587
Reputation: 279
Your code is kinda OK and PHP is secure
The problem here is how you use AES-GCM. The tag length is a security parameter, meaning you can choose any size. Minimal recommanded size is 96bits, and you should check the size.
In your code, you do not check the tag size, openssl_decrypt()
does what you ask : validates a 1-byte tag.
PHP would know if this broke, see test line 31
Final thought : be careful when using low-level cryptography, you could use Sodium which is embedded with PHP>7.2
Upvotes: 3