Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openssl_decrypt tag value

I'm using the openssl_encrypt / decrypt method in my website but i'm having some troubles with the $tag option

openssl_encrypt ( $data, $method, $key, $options, $iv, $tag )
openssl_decrypt ( $data, $method, $key, $options, $iv, $tag )

from http://php.net/manual/en/function.openssl-encrypt.php, the definition of tag is: The authentication tag passed by reference when using AEAD cipher mode (GCM or CCM). But i didn't understand it.

I tried it in my codes

$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);

if (in_array($cipher, openssl_get_cipher_methods())){       
    $encryptedData = openssl_encrypt($data,$cipher,$key,$option,$iv,$tag);
    echo $encryptedData;

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo $decryptedData;
}

i got this result:

encrypted text: Vlx/yKkPhg0DpD0YKvnFKRiCh/I=
decrypted text: text to be encrypted

which is correct. but if i directly decrypt the encrypted text this way:

$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);

if (in_array($cipher, openssl_get_cipher_methods())){
    $encryptedData = "Vlx/yKkPhg0DpD0YKvnFKRiCh/I=";

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo $decryptedData;
}

i'm getting:

Notice: Undefined variable: tag

if someone could explain to me why this is happening and what should be the value of $tags. thanks

like image 592
Joey Azar Avatar asked Aug 23 '18 06:08

Joey Azar


People also ask

What is IV in openssl_encrypt?

An initialization vector (IV) is an arbitrary number that can be used with a secret key for data encryption to foil cyber attacks. This number, also called a nonce (number used once), is employed only one time in any session to prevent unauthorized decryption of the message by a suspicious or malicious actor.

What is tag in Openssl?

from http://php.net/manual/en/function.openssl-encrypt.php, the definition of tag is: The authentication tag passed by reference when using AEAD cipher mode (GCM or CCM).

What is Openssl_raw_data?

OPENSSL_RAW_DATA just tells openssl_encrypt() to return the cipherText as ... raw data. By default, it returns it Base64-encoded. The source code is easy to find, but not really useful as it's not like the flag does anything extra ... The opposite - it tells PHP not to do the extra step of Base64 encoding.

What is openssl_encrypt?

The openssl_encrypt() ope function can be applied for encrypting data in PHP. The syntax of openssl_encrypt() will look as follows: string openssl_encrypt( string $data, string $method, string $key, $options = 0, string $iv, string $tag= NULL, string $aad, int $tag_length = 16 )


1 Answers

The tag that PHP is complaining about is an essential aspect of AES when using GCM mode of operation. In this mode, not only does the AES block cipher get applied, but an authentication tag gets calculated as well. It is an array of bytes that represents a MAC (Message Authentication Code) that can be used to verify the integrity of the data and wen decrypting. That same tag needs to be provided to do that verification. See the Wikipedia page about Galois/Counter Mode for more details.

So in order to successfully decrypt that ciphertext, you need to capture the $tag variable resulting from the openssl_encrypt() invocation and feed it into the openssl_decrypt() invocation. You did not do that, hence the complaint about the missing tag. Note that the tag (typically) contains non-readable characters so it is more convenient to store it in a base64 encoded format.

In addition to the $tag variable, you should also provide the same value for the $iv variable to the openssl_decrypt() method as you used in the openssl_encrypt() invocation. Again, base64 encoding makes that easier.

A quick test below demonstrates all this, where I first modified your script to print more stuff and then used the provided script to decrypt:

$ php test1.php 
iv base64-ed: vBKbi8c6vCyvWonV
plaintext: text to be encrypted
ciphertext base64-ed: z28spOd3UEDmj+3a8n/WK11ls7w=
GCM tag base64-ed: OIAggQCGUbPgmPN6lFjQ8g==
$ php test2.php 
decrypted ciphertext: text to be encrypted

where the code for test2.php is the following:

$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$iv = base64_decode("vBKbi8c6vCyvWonV");

if (in_array($cipher, openssl_get_cipher_methods())){       

    $encryptedData = "z28spOd3UEDmj+3a8n/WK11ls7w=";
    $tag = base64_decode("OIAggQCGUbPgmPN6lFjQ8g==");

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo("decrypted ciphertext: ".$decryptedData."\n");
}
like image 150
Reinier Torenbeek Avatar answered Oct 08 '22 17:10

Reinier Torenbeek