简体   繁体   中英

AES-256-GCM mode decryption fails in php

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM