Friday, November 02, 2007

Setting up GnuPG (GPG) for use with PHP

Step 1 (failed):
$ pecl install gnupg

downloading gnupg-1.3.1.tar ...
Starting to download gnupg-1.3.1.tar (-1 bytes)
.............done: 124,416 bytes
5 source files, building
running: phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606
`phpize' failed

Step 2 (success). Some information drawn from http://www.php.net/manual/en/install.pecl.php, a basic tutorial on how to install PECL extensions.
$ cd /usr/lib64/php/extensions

(This is where my PHP extensions [files with .so extension] are stored)
$ pecl download gnupg
$ tar -zxvf gnupg-1.3.1.tgz
$ cd gnupg-1.3.1/
$ phpize
$ ./configure
$ make
$ make install

"gnupg.so" now appears in /usr/lib64/php/extensions
Now I need to install the extension in the php.ini file
$ whereis php.ini

/etc/php.ini
$ vi /etc/php.ini

Find the list of extensions in php.ini, in my case headed by "[extension section]". Add "extension=gnupg.so" to the end of the list, save and exit.
Now I need to restart apache so the extension takes effect.
$ apache2ctl graceful

Now do some PHP coding. Assumes you have GnuPG (gpg) installed, and have set up your key pair ("gpg --gen-key"). Some of these steps might be unnecessary, but after hours of fiddling around, I'm not about to walk through it again and find the essential ones.
/* Change this to your own path */
putenv("GNUPGHOME=/home/bch36/.gnupg/");

$encrypted_data = file_get_contents("encrypted.gpg");

$res = gnupg_init();

gnupg_seterrormode($res,GNUPG_ERROR_WARNING);

/* Change this to your own fingerprint. Find your fingerprint by running "gpg --fingerprint" from the commandline. Comment this out when everything works. */
print_r(gnupg_keyinfo($res,"ASDF1234QWER5678ZXCV9012ASDF3456QWER7890"));

/* Put your own fingerprint and passphrase here. Also, this function will fail unless you see Important Note #1 below */
gnupg_adddecryptkey($res, "ASDF1234QWER5678ZXCV9012ASDF3456QWER7890", "put your secret passphrase here");

/* You'll want to comment this out when everything is working */
echo gnupg_geterror($res);

/* This function will fail unless you see Important Note #2 below */
$plain = gnupg_decrypt($res, $encrypted_data);

Important Notes:
1. To get gnupg_keyinfo() to work, you'll need to let your webserver have some access to your keyring. Do the following (replace "www" with the group that your own webserver runs under):
> cd /home/bch36/.gnupg
> chown :www pubring.gpg trustdb.gpg
> chmod 660 pubring.gpg trustdb.gpg

2. To get gnupg_decrypt() to work, you'll need to grant more access. Note that the webserver will now have access to your secret key! However, if you don't do the following, the gnupg_decrypt() function will fail and you'll get the following warning when printing out gnupg_geterror(): "Warning: gnupg_adddecryptkey() [function.gnupg-adddecryptkey]: get_key failed in ..."
> chown :www secring.gpg
> chmod 660 secring.gpg

As a possible point of interest, I'm only doing decryption because I want a remote webpage to use Javascript to PGP encrypt data and send it to my PHP file, which can then decrypt it. I guess it's a workaround for not having SSL. I'll try to post an entry about the client-side next (Javascript PGP).

15 comments:

faceleg said...

Thankyou very much for posting this - the part about the correct permissions & group ownership was extremely helpful for me!

Naresh Kumar నరేష్ కుమార్ said...

Hi,

Can you please let me know what should be secret passphrase in following code? Is it any random text? or related to any finger print or public key?

gnupg_adddecryptkey($res, "ASDF1234QWER5678ZXCV9012ASDF3456QWER7890", "put your secret passphrase here");

Thanks,
Palani

The Writer said...

Naresh: when you run "gpg --gen-key", that command will ask for a passphrase so it can generate the fingerprint. You will make up a passphrase and use it there.

Naresh Kumar నరేష్ కుమార్ said...

Thanks for your quick reply. I am still getting errors and unable to decrypte a pgp encrypted XML file.


We have a public key and secret passphrase and a pgp decrypted XML fil and I need to decrypt it using PHP.


Here is my program:




Here is the output and the error I am getting:

Array
(
[imported] => 0
[unchanged] => 1
[newuserids] => 0
[newsubkeys] => 0
[secretimported] => 0
[secretunchanged] => 0
[newsignatures] => 0
[skippedkeys] => 0
[fingerprint] =>
)


Array
(
[0] => Array
(
[disabled] =>
[expired] =>
[revoked] =>
[is_secret] =>
[can_sign] => 1
[can_encrypt] => 1
[uids] => Array
(
[0] => Array
(
[name] => My Company Name
[comment] => PGP Key for Testing
[email] => my@email.com
[uid] => UID (PGP Key for Testing)
[revoked] =>
[invalid] =>
)

)

[subkeys] => Array
(
[0] => Array
(
[fingerprint] =>
[keyid] =>
[timestamp] =>
[expires] => 0
[is_secret] =>
[invalid] =>
[can_encrypt] =>
[can_sign] => 1
[disabled] =>
[expired] =>
[revoked] =>
)

[1] => Array
(
[fingerprint] =>
[keyid] =>
[timestamp] =>
[expires] => 0
[is_secret] =>
[invalid] =>
[can_encrypt] => 1
[can_sign] =>
[disabled] =>
[expired] =>
[revoked] =>
)

)

)

)



Warning: gnupg_adddecryptkey() [function.gnupg-adddecryptkey]: get_key failed in /mysite.com/myfilename.php on line 28

Warning: gnupg_decrypt() [function.gnupg-decrypt]: decrypt failed in /www/v3dev.ecampusmanager.com/DecryptingPgpFileTest.php on line 31

Can you please let me know how to fix this error or what are the changes to be done to decrypt? For your information, my server GPGme version is 1.1.5 and Extension Version is 1.3.2-dev (Found in "gnupg" section of phpinfo output)

The Writer said...

Naresh, it appears you're getting the error that I mentioned in note #2 above. Read through that again and see if it solves your problem.

Naresh Kumar నరేష్ కుమార్ said...

I have changed permission to following files to 660 (through FTP), but no luck.

pubring.gpg
pubring.gpg~
secring.gpg
trustdb.gpg


Anything else I need to do? Please let me know.

Thanks
N Naresh Kumar

The Writer said...

You also must change the owner of the files to the webserver, as outlined in my note #2 above. On my machine, the owner is "www". I'm not sure what it would be on yours, but it sounds like that's the part you're still missing.

Naresh Kumar నరేష్ కుమార్ said...

Hi,

Can you please let me know how to find and change owner of webserver?

I tried like this:

cd /home/MyUserName/.gnupg/

"ls -a" command showed following information

total 28
-rw-r--r-- 1 MyUserName MyGroupName 50 2012-01-12 12:09 gpg-agent-info-compindia
-rw------- 1 MyUserName MyGroupName 9398 2011-12-27 17:10 gpg.conf
drwx------ 2 MyUserName MyGroupName 4096 2012-01-12 12:09 private-keys-v1.d
-rw-rw---- 1 MyUserName MyGroupName 0 2011-12-27 17:10 pubring.gpg
-rw------- 1 MyUserName MyGroupName 600 2011-12-30 11:17 random_seed
-rw-rw---- 1 MyUserName MyGroupName 0 2011-12-27 17:10 secring.gpg
-rw-rw---- 1 MyUserName MyGroupName 40 2012-01-12 11:55 trustdb.gpg


cd /etc/apache2/
ls -l
total 68
-rw-r--r-- 1 root root 7994 2011-11-03 07:41 apache2.conf
drwxr-xr-x 2 root root 4096 2011-12-23 20:12 conf.d
-rw-r--r-- 1 root root 1169 2011-11-03 07:41 envvars
-rw-r--r-- 1 root root 0 2011-12-23 19:42 httpd.conf
-rw-r--r-- 1 root root 31063 2011-11-03 07:41 magic
drwxr-xr-x 2 root root 4096 2011-12-23 20:11 mods-available
drwxr-xr-x 2 root root 4096 2011-12-23 19:45 mods-enabled
-rw-r--r-- 1 root root 750 2011-11-03 07:41 ports.conf
drwxr-xr-x 2 root root 4096 2011-12-23 19:42 sites-available
drwxr-xr-x 2 root root 4096 2011-12-23 19:42 sites-enabled


cd /home/neelamegan/.gnupg/
sudo chown :root pubring.gpg trustdb.gpg
chmod 660 pubring.gpg trustdb.gpg
sudo chown :root secring.gpg
chmod 660 secring.gpg

(For your information, I am checking this ubuntu OS and I see those 4 files - pubring.gpg, secring.gpg, pubring.gpg~, trust.gpg in /tmp folder too.)

Pleset let me know how to change the owner of those files to the webserver.

Thanks,
Naresh Kumar

The Writer said...

In the comment you posted, you're changing the user of the three files (pubring.gpg, trustdb.gpg, and secring.gpg) to "root". This will not work, since the web server does not have access to root's files.

To discover which user the webserver runs as, create a php script in your web directory and put the following php code in it:



View this php script from a web browser, and it will print the user that the webserver is running as. On the computer I used when I wrote this blog post, the user was "www". On my current computer, the user is "www-data". Another common user you'll see is "nobody".

Take whichever username appears on the webpage and use that when you set the owner:

sudo chown :[USERNAME_HERE] pubring.gpg trustdb.gpg secring.gpg
sudo chmod 660 pubring.gpg trustdb.gpg secring.gpg

Naresh Kumar నరేష్ కుమార్ said...

I don't see any PHP script/coding (It seems blogger removed server side scripts in comments). Could you please post it again without php tags?

Thanks,
Naresh Kumar

The Writer said...

Sorry, the php code is:

echo exec('whoami');

Naresh Kumar నరేష్ కుమార్ said...

It showed 'www-data' (for that script) in my browser and I executed following commands:

sudo chown :www-data pubring.gpg trustdb.gpg secring.gpg
sudo chmod 660 pubring.gpg trustdb.gpg secring.gpg

But, no luck. Please help.

The Writer said...

Sorry, I'm afraid you're on your own at this point. I have nothing else to try.

Good luck!

Naresh Kumar నరేష్ కుమార్ said...

I was using public key to get fingerprint. Now, I have used private key to get fingerprint and able to decrypt pgp files.

Thanks,
N Naresh Kumar

Naresh Kumar నరేష్ కుమార్ said...

I was using public key to get fingerprint. Now, I have used private key to get fingerprint and able to decrypt pgp files.

Thanks,
N Naresh Kumar