Repository navigation
openssl_seal()/_open() is not able to handle gcm cipers, e.g. aes-256-gcm #7737
Copy link
Copy link
Open
Description
Description
The following code:
<?php
const NUM_KEYS = 2;
for ($i = 0; $i < NUM_KEYS; $i++) {
$keys[] = $key = openssl_pkey_new();
$details = openssl_pkey_get_details($key);
$pubKeys[] = $details['key'];
$privKeys[] = openssl_pkey_get_private($key);
}
$data = 'Test Data String';
$ciphers = [
'aes-256-ctr',
'aes-256-gcm',
];
foreach ($ciphers as $cipherAlgo) {
echo "*** TESTING $cipherAlgo ***" . PHP_EOL . PHP_EOL;
$iv = \random_bytes(openssl_cipher_iv_length($cipherAlgo));
$result = openssl_seal($data, $sealedData, $sealedKeys, $pubKeys, $cipherAlgo, $iv);
echo "DATA : " . strlen($data) . ' ' . $data . PHP_EOL;
echo "IV-LEN: " . openssl_cipher_iv_length($cipherAlgo) . PHP_EOL;
echo "IV : " . bin2hex($iv) . PHP_EOL;
echo "ENC DATA: " . strlen($sealedData) . ' ' . bin2hex($sealedData) . PHP_EOL;
echo "RESULT: " . ($result ? 'true' : 'false') . PHP_EOL;
echo PHP_EOL;
// Try decrypt
foreach ($keys as $i => $key) {
$decrypted = null; // ;)
$result = openssl_open($sealedData, $decrypted, $sealedKeys[$i], $key, $cipherAlgo, $iv);
echo "OPEN: " . $decrypted . PHP_EOL;
echo "RESULT: " . ($result ? 'true' : 'false') . PHP_EOL;
$result = openssl_private_decrypt($sealedKeys[$i], $unsealedKey, $key);
echo "UNSEAL: " . bin2hex($unsealedKey) . PHP_EOL;
echo "RESULT: " . ($result ? 'true' : 'false') . PHP_EOL;
echo "DECRYPT: " . openssl_decrypt($sealedData, $cipherAlgo, $unsealedKey, OPENSSL_RAW_DATA, $iv) . PHP_EOL;
}
echo PHP_EOL;
}Resulted in this output:
$ ./openssl-seal-test.php
*** TESTING aes-256-ctr ***
DATA : 16 Test Data String
IV-LEN: 16
IV : 37ff67041864b987b8ec2dcd0879f55e
ENC DATA: 16 2a748aa6ae176caf59cf22868304d65a
RESULT: true
OPEN: Test Data String
RESULT: true
UNSEAL: 8745e00bdf3d88bd1caa8ec0150a9b369eade92e57fc2d26ae283f224c66af14
RESULT: true
DECRYPT: Test Data String
OPEN: Test Data String
RESULT: true
UNSEAL: 8745e00bdf3d88bd1caa8ec0150a9b369eade92e57fc2d26ae283f224c66af14
RESULT: true
DECRYPT: Test Data String
*** TESTING aes-256-gcm ***
DATA : 16 Test Data String
IV-LEN: 12
IV : 033b1589f62bebbfffa3adda
ENC DATA: 16 a531f88fc51e373235c928cae1eb7c29
RESULT: true
OPEN:
RESULT: false
UNSEAL: 600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT: true
DECRYPT:
OPEN:
RESULT: false
UNSEAL: 600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT: true
DECRYPT:
But I expected this output instead:
[...]
*** TESTING aes-256-gcm ***
DATA : 16 Test Data String
IV-LEN: 12
IV : 033b1589f62bebbfffa3adda
ENC DATA: 16 a531f88fc51e373235c928cae1eb7c29
RESULT: true
OPEN: Test Data String
RESULT: true
UNSEAL: 600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT: false
DECRYPT:
OPEN: Test Data String
RESULT: true
UNSEAL: 600cf6e76cf4ae9d48a881e0649af4682aa9065e63bec515a6b8c9678e398d36
RESULT: false
DECRYPT:
The point is that the gcm-cipher need the authentication tag for decrypting the data. This however does not seem to be saved by the openssl_seal() function. I have also placed a question in the OpenSSL issue tracker: openssl/openssl#17235
PHP Version
PHP 8.0.13 (cli) (built: Nov 27 2021 17:17:19) ( ZTS )
Operating System
Gentoo Linux 5.15.6, but should not matter
Reactions are currently unavailable
Activity
cmb69 commentedon Dec 16, 2021
@bukka, could you please clarify whether this is a bug, or a feature request, or a documentation issue?
rotdrop commentedon Dec 16, 2021
Well, AFAIK PHP's openssl_seal() is not able to use the gcm-ciphers. So probably
openssl_seal()does not complain (return value is true) this is also a bug. Arguably, the encoding does succeed. Its just that there is no chance to decode the sealed data without the authentication tag.There is also an attempt to use openssl_seal() with
aes-256-gcmwithin the Nextcloud-project: nextcloud/server#25551bukka commentedon Dec 16, 2021
I don't think there's any issue in OpenSSL so you can probably close that linked ticket in OpenSSL. This is just a missing functionality in PHP and it's really a feature request. Basically
EVP_Seal*are just wrappers aroundEVP_Encrypt*that allows encrypting the key with the supplied pkey. What PHP doesn't do is to provide a way to return a tag. Although you could probably write your version of sealing in PHP to give you the same functionality ( you might get an idea when you look to https://github.com/openssl/openssl/blob/defe51c178e3dc9f07514c179121021fd78691b4/crypto/evp/p_seal.c ). That said we could possibly add extra parameters toopenssl_sealto return tag and also extendopenssl_openaccordingly. So that's why this should be a feature request.rotdrop commentedon Dec 16, 2021
So then. Kind of a missing feature.
You are probably right that an extra parameter
string &$tagor so is more in the spirit of the current interface than simply appending the tag to the encrypted keys.I am still tempted to interpret the current state as a documentation bug. It is not so clear from reading the manual that the the ...-gcm ciphes to not work out of the box. And it still feels a little bit weird that
openssl_seal()very happily accepts the ...-gcm cipher just to produce something which cannot be decrypted again.bukka commentedon Dec 16, 2021
I agree that it should be noted in docs but doc bugs should be reported to https://github.com/php/doc-en . So for this repo, it's just a feature request... :)
rotdrop commentedon Dec 16, 2021
Agreed. I have just filed an issue which, well, is just a link to this issue.
come-nc commentedon Dec 8, 2022
@bukka Hello, I see you are listed as maintainer for the openssl extension.
Regarding this issue:
openssl_sealfunction somehow deprecated? I see negative comments on https://www.php.net/manual/function.openssl-seal.php on both use of RC4 and PKCS1 v1.5. Does it make sense to use this function with newer ciphers in your opinion, or is there another more suited solution?MohamedAbuZamil commentedon Aug 3, 2023
Fix phpGH-7737: openssl_seal/openssl_open do not handle tagged algori…
sgolemon commentedon Dec 11, 2025
Put up #20687 to implement the extra parameter as suggested by @bukka
The relevant OpenSSL APIs are:
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, tag_buf);andEVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag_buf);Fix GH-7737: openssl_seal/openssl_open do not handle tagged algorithms (
Revert "Fix GH-7737: openssl_seal/openssl_open do not handle tagged a…
Revert "Fix GH-7737: openssl_seal/openssl_open do not handle tagged a…
ndossche commentedon Dec 19, 2025
Reopened because the PR was reverted