Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated messages by openpgp-php are intermittently undecryptable by openpgp-php #137

Open
paulie51 opened this issue Jun 21, 2024 · 1 comment

Comments

@paulie51
Copy link

paulie51 commented Jun 21, 2024

Hi,
We have trying to migrate from php-gnupg to openpgp-php with an existing application (and therefore keys).

We were seeing inconsistent results in testing and eventually when we couldn't find a cause took to running bulk loops of message encryption and decryption to see if they were stable.... This highlighted the inconsistent issues we were seeing, depending on various factors (message length, potentially key source, key size) between in 1 in 30 and 1 in 5 messages generated using the below code would result in this error :

PHP Fatal error:  Uncaught OutOfRangeException: Ciphertext representative out of range in openpgp-php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php:68
Stack trace:
#0 openpgp-php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php(320): phpseclib3\Crypt\RSA\PrivateKey->rsadp(Object(phpseclib3\Math\BigInteger))
#1 openpgp-php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php(441): phpseclib3\Crypt\RSA\PrivateKey->rsaes_pkcs1_v1_5_decrypt(Object(phpseclib3\Math\BigInteger))
#2 openpgp-php/lib/openpgp_crypt_rsa.php(218): phpseclib3\Crypt\RSA\PrivateKey->decrypt('\xBB\x9C\xD4zt\e\xB3\x90V/\xF64\x84\xFF3...')
#3 openpgp-php/lib/openpgp_crypt_rsa.php(200): OpenPGP_Crypt_RSA::try_decrypt_session(Object(phpseclib3\Crypt\RSA\PrivateKey), '\xBB\x9C\xD4zt\e\xB3\x90V/\xF64\x84\xFF3...')
#4 openpgp-php/examples/deASCIIdeCryptCompressed.php(39): OpenPGP_Crypt_RSA->decrypt(Object(OpenPGP_Message))
#5 {main} thrown in openpgp-php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php on line 68`

This is tested with multiple different keys generated from different sources and with different key sizes, against mainly PHP 8.1 but also 8.0 and 8.2. We've also tested against different architectures and different builds of PHP.

We've also tested this without using compression and with multiple message sizes (generally the larger the message the more frequently this occurs). We've also tested it with and without generating the ASCII message and decrypting from there. Nothing we've found has prevented a message being generated intermittently that openpgp-php then cannot decipher.

The script being used :

<?php

// USAGE: php examples/deASCIIdeCrypt.php secretkey.asc password message.asc
// Derived from examples/deASCIIdeCrypt.php and examples/encryptdecrypt.php

@include_once dirname(__FILE__).'/../vendor/autoload.php';
require_once dirname(__FILE__).'/../lib/openpgp.php';
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';
require_once dirname(__FILE__).'/../lib/openpgp_crypt_symmetric.php';

$keyASCII = file_get_contents("generated.private.asc");
$pubkeyASCII = file_get_contents("generated.public.asc");
$pass = "testing";

$message = "some random message";

$publicKey = OpenPGP_Message::parse(OpenPGP::unarmor($pubkeyASCII, 'PGP PUBLIC KEY BLOCK'));

$data = new OpenPGP_LiteralDataPacket($message, array('format' => 'u'));

$compressed = new OpenPGP_CompressedDataPacket($data);
$encrypted = OpenPGP_Crypt_Symmetric::encrypt($publicKey, new OpenPGP_Message([$compressed]));

//$encrypted = OpenPGP_Crypt_Symmetric::encrypt($publicKey, new OpenPGP_Message(array($data)));
//$encryptedmessage = OpenPGP::enarmor($encrypted->to_bytes(), 'PGP MESSAGE');

$keyEncrypted = OpenPGP_Message::parse(OpenPGP::unarmor($keyASCII , 'PGP PRIVATE KEY BLOCK'));

// Try each secret key packet
foreach($keyEncrypted as $p) {
        //if(!($p instanceof OpenPGP_SecretKeyPacket)) continue;
  if(!(get_class($p) == 'OpenPGP_SecretKeyPacket')) continue;

  $key = OpenPGP_Crypt_Symmetric::decryptSecretKey($pass, $p);

        //$msg = OpenPGP_Message::parse(OpenPGP::unarmor($encryptedmessage, 'PGP MESSAGE'));
  $msg = $encrypted;

        $decryptor = new OpenPGP_Crypt_RSA($key);
        $decrypted = $decryptor->decrypt($msg);

        //var_dump($decrypted);
}

We then called it in a loop repeatedly breaking out when the error above occurs, changing various parameters.

We've been unable to find a cause for this inconsistent behaviour, and its probably worth noting that the generated messages we have tested have been decryptable by other means (ie gpg on MacOS), so unless you were openpgp-php -> openpgp-php this may not manifest.

@singpolyma
Copy link
Owner

Can you send a specific example of a key and message that could not decrypt with this library but did work with another tool?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants