3

Here's my code:

<?php
$secret="This is a secret message.";
$key="Secret key.";
$iv=openssl_random_pseudo_bytes(12);
$method="aes-256-gcm";

$encrypted=openssl_encrypt($secret,$method,$key,false,$iv);
$decrypted=openssl_decrypt($encrypted,$method,$key,false,$iv);

echo $encrypted;
echo "<br>";
echo $decrypted;
?>

I've got the encrypted message, but the decryption gives no result or error message. The same code is working with another method, like aes-256-cbc.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Pethő Jonatán
  • 308
  • 4
  • 11
  • Can you try with `true` instead of `false`? Bugger PHP's documentation, but if I read this right, it should return raw output when put to true (or 1?). – Maarten Bodewes Feb 14 '15 at 16:12
  • I tried it, but didn't work for me. – Pethő Jonatán Feb 14 '15 at 18:26
  • What size is your ciphertext? Did you test if you get a result from the encryption? – Maarten Bodewes Feb 14 '15 at 18:53
  • Never mind, I've got it running... just a second... – Maarten Bodewes Feb 14 '15 at 18:55
  • `w1ZrOTTb7CFlhOILDJTUYSLWVjCNFZALbw==` – Pethő Jonatán Feb 15 '15 at 09:50
  • I guess I should call this function an other way then the others because AES-GCM has an authenticating function if I'm right. But I hasn't been understood this method completly yet. – Pethő Jonatán Feb 15 '15 at 09:54
  • I'm not even sure if anyone tried to get GCM working in the wrapper class. I can replicate your result, but that doesn't mean much. – Maarten Bodewes Feb 15 '15 at 13:52
  • It looks like the tag is entirely missing from action, Pethő. The size of the output seems to consist of as many bytes as the input, meaning that just the underlying CTR encryption is returned (after key derivation for CTR and alteration of the counter, you cannot just decrypt in CTR mode). Of course, without any authentication tag to work with, decryption *should* fail. – Maarten Bodewes Feb 15 '15 at 14:09
  • I didn't found any description or documentation how should I give it the authentication tag. – Pethő Jonatán Feb 15 '15 at 15:55
  • I'm guessing it is simply not there. This function was never engineered to work with authenticated encryption (to my knowledge). This is a wrapper method that simply calls the underlying library. Instead you could opt for CBC + HMAC over IV & ciphertext. – Maarten Bodewes Feb 15 '15 at 16:32
  • Yes, I also found this solution as alternative. Thank you for your help :) – Pethő Jonatán Feb 15 '15 at 16:40

1 Answers1

2

Testing his out on my system (PHP 5.3.10 using return OpenSSL 1.0.1 internally) returns a ciphertext that has the same length as the plaintext (message).

This means that GCM encryption does not return the authentication tag, just the internal CTR mode encryption. This is likely because the PHP wrapper simply calls the OpenSSL interface directly and doesn't use the following code:

if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
    handleErrors();

which was found in the sample code of OpenSSL EVP ("higher level") encryption using GCM. In other words, the tag needs to be retrieved separately.

Handling the tag separately actually does make sense - it makes it possible to create a more online implementation that uses less buffering - but that doesn't help you here. You can use AES-CBC followed by a HMAC over the IV and ciphertext to replace GCM mode. Using a separate key for encryption and the authentication tag would make this scheme somewhat more secure.


PS you cannot directly use CTR mode decryption to retrieve the plaintext again because of differences in initialization.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • No is also an answer, I suppose :( – Maarten Bodewes Feb 15 '15 at 17:30
  • 1
    AES/GCM is also broken from OpenSSL's command line tools. See [AES-GCM failing from Command Line Interface](https://groups.google.com/d/msg/mailing.openssl.users/rx1ZNQAccAY/JNbS9pFa79wJ) on the OpenSSL users list. – jww Feb 16 '15 at 02:07
  • @jww fails the same way too; seems like the wrapper uses the CLI interface (otherwise it would not know how to parse the algorithm string) – Maarten Bodewes Feb 16 '15 at 03:31
  • 1
    [PHP 7.1 will support AEAD modes, returning the tag and AAD.](https://wiki.php.net/rfc/openssl_aead) – bishop Feb 16 '16 at 21:10