Reputation: 221
I'm trying to decrypt a gpg file with the private key using the php GnuPG functions. But, when attempting to decrypt it looks like php is just hanging or taking forever to finish. I'm trying to decrypt a simple test file with one sentence in it.
I can decrypt the file offline (e.g. using GNU Privacy Assistant).
I think I have set up the permissions okay-
-bash-4.1$ gpgconf --list-dirs
/home/jdoe/.gnupg/gpg.conf, perms: 0770
/home/jdoe/.gnupg/pubring.gpg~, perms: 0770
/home/jdoe/.gnupg/secring.gpg, perms: 0660
/home/jdoe/.gnupg/private-keys-v1.d, perms: 0700
/home/jdoe/.gnupg/random_seed, perms: 0600
/home/jdoe/.gnupg/pubring.gpg, perms: 0770
/home/jdoe/.gnupg/trustdb.gpg, perms: 0770
But, if I write a new file to "/home/jdoe/.gnupg/" it comes up with 644 permissions (not sure if this matters).
/home/jdoe/.gnupg/xxxtest.txt.gpg, perms: 0644
I (think) I have imported the private key successfully. The KeyInfo is below. The relevant key has a fingerprint and key id with 888 (I've replaced their actual values with 888). I'm including all the keys in case it is relevant (I've replace the non-relevant fingerprint/key information with 777).
$info = $gpg->keyinfo(''); echo 'Key info:' . print_r($info, true);
Array ( [0] => Array ( [disabled] => [expired] => [revoked] => [is_secret] => [can_sign] => 1 [can_encrypt] => 1 [uids] => Array ( [0] => Array ( [name] => ApacheTest [comment] => Testing [email] => apache@localhost [uid] => ApacheTest (Testing) [revoked] => [invalid] => ) ) [subkeys] => Array ( [0] => Array ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1203433839 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => [can_sign] => 1 [disabled] => [expired] => [revoked] => ) [1] => Array ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1203433840 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => 1 [can_sign] => [disabled] => [expired] => [revoked] => ) ) ) [1] => Array ( [disabled] => [expired] => [revoked] => [is_secret] => [can_sign] => 1 [can_encrypt] => 1 [uids] => Array ( [0] => Array ( [name] => John Doe [comment] => [email] => [email protected] [uid] => John Doe [revoked] => [invalid] => ) ) [subkeys] => Array ( [0] => Array ( [fingerprint] => 888 [keyid] => 888 [timestamp] => 1224013510 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => [can_sign] => 1 [disabled] => [expired] => [revoked] => ) [1] => Array ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1224013510 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => 1 [can_sign] => [disabled] => [expired] => [revoked] => ) ) ) )
My problem is, when attempting to decrypt with the code below it looks like php is just hanging or taking forever to finish (exceeding than the max_execution_time in reality, but not showing an error message about it).
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
putenv("GNUPGHOME=/home/jdoe/.gnupg");
$encryptedContent = file_get_contents($filePathAndName);
$pw = [];
$fingerprint = [];
if($gpg->adddecryptkey($recipient, $pw)) {
echo "Add decrypt key returned true.";
} else {
echo "Could not add decrypt key. GPG error: " . $gpg -> geterror();
}
//I know we get to this spot
try {
$plaintext = $gpg->decrypt($encryptedContent);
echo '<pre>' . $plaintext . '</pre>';
} catch (Exception $e) {
die('ERROR: ' . $e->getMessage());
}
Any ideas on why this isn't working? Thanks so much.
============== Output from ls -la /home/jdoe/.gnupg
drwxrwx--- 3 jdoe apache 4096 Mar 31 23:45 .
drwxr-xr-x 19 jdoe root 12288 Apr 1 09:39 ..
-rwxrwx--- 1 jdoe apache 9188 Mar 28 15:36 gpg.conf
drwx------ 2 apache apache 4096 Mar 31 21:26 private-keys-v1.d
-rwxrwx--- 1 apache apache 2479 Mar 31 21:26 pubring.gpg
-rwxrwx--- 1 apache apache 913 Mar 31 20:28 pubring.gpg~
-rw------- 1 apache apache 600 Mar 31 20:32 random_seed
-rw-rw---- 1 jdoe apache 1978 Mar 28 21:05 secring.gpg
-rwxrwx--- 1 apache apache 10 Mar 31 20:28 test.txt
-rwxrwx--- 1 jdoe apache 1200 Mar 31 20:28 trustdb.gpg
-rw-r--r-- 1 apache apache 347 Mar 31 23:30 xxxtest.txt.gpg
Can you decrypt the file from the command line, and how long does it take?
Will get back to you with this information (working with an SA on this, I only have ftp access to the machine).
Try increasing the error reporting of PHP?
Already done... it just spins (which I assume means it times out, out exit_on_timeout is off). I've tried it with a 10 minute and 30 second timeout. Result is the same. The test file we are decrypting is less than 100 characters.
You might want to try not setting the home directory, but importing the key using import($keydata)
Same result
Tried setting a different home directory?
I created /home/jdoe/.gnupg/temp, chmod permissions to 777. I set this as a home directory for gpg. I attempted to import the private key. But, $gpg->keyinfo('') returns nothing. This time when trying to $gpg->adddecryptkey, it fails with this error - "Uncaught exception 'Exception' with message 'get_key failed'".
Thanks
Upvotes: 3
Views: 2062
Reputation: 1240
In case someone is still facing this issue (just like I was), please read this :
As of gnupg version 2, it is not possible to pass a plain password any more. The parameter is simply ignored. Instead, a pinentry application will be launched in case of php running in cli mode. In cgi or apache mode, opening the key will fail. The simplest solution is to use keys without passwords.
from : http://php.net/manual/en/function.gnupg-decrypt.php
My php script running via cron would always fail to decrypt until i removed the passphrase. I tried using the key without passphrase and it worked fine for me.
Cheers!
Upvotes: 1
Reputation: 1777
I ran into the same problem as you today. Endless troubleshooting on how to decrypt a simple file. PHP would hang endlessly, even though I was decrypting a file that was 568 bytes. The solution is to not use the built-in PHP functions, and instead use the PEAR Crypt_GPG library
Start by installing the library (1.4.0b4 as suggested in another answer here):
pear install Crypt_GPG-1.4.0b4
Once that's done, go into a php file and use the following code as an example:
set_include_path("/usr/share/pear"); //ADD PEAR FOLDER TO INCLUDE PATH
require_once 'Crypt/GPG.php'; //INCLUDE PEAR LIBRARY
$options = array('homedir' => '/tmp'); //KEYRING DIRECTORY
$gpg = new Crypt_GPG($options); //MAKE NEW GPG OBJECT
Now, familiarize yourself with the Crypt_GPG class: http://pear.php.net/package/Crypt_GPG/docs/latest/Crypt_GPG/Crypt_GPG.html
Don't forget to add your public key (Only needs to be run once):
$gpg->importKey(file_get_contents("/path/to/public-key.key"));
List keys:
$keys = $gpg->getKeys();
print_r($keys);
Add a decryption key to your GPG object
$gpg->addDecryptKey($keys[0],"key passphrase");
Now, decrypt your file:
file_put_contents($unencrypted_file,$gpg->decrypt(file_get_contents($encrypted_file)));
I hope this helps people, because wow... I spent literally all day just trying to figure out how to decrypt a file in PHP. Something that I can do in C# in about 5 minutes.
Upvotes: 0
Reputation: 51
I had the same problem while switching to a new server. The problem for me was that the new server is using gpg2, and the current stable version (1.3.2) of Crypt_GPG does not support this. For me it solved the problem to upgrade too the new beta version (1.4.0b4) of Crypt_GPG.
Upvotes: 0