If you liked this site, please feel free to help me out with the upkeep!


Get Firefox!

Valid HTML 4.01 Transitional

Home > Programming > PHP and PGP

How to use PGP with PHP

(c) Kelv 2000. Republished on alt.php.faq with permission.

The following are assumed...

  1. You have shell access to the system you are setting this up on.
  2. The machine is running Linux, or some other Unix variant.
  3. You are comfortable with using the shell.
  4. You understand how PGP works.

Where to get PGP or GnuPG from?

If you are starting from scratch and don't have a mail client either, I recommend you install Thunderbird, as there are versions of it for almost every operating system. You then need to get the Enigmail extension and GnuPG. For a full list of PGP apps, go to pgpi.org.

Generate a Keypair

The first thing is to generate a key pair. This comprises of a public and private key, the former of which you upload to the server. The private key should be kept on the machine you plan to decrypt the messages on. Keep it safe! Back it up! Don't forget the passphrase! For the purpose of these examples, our recipients public/private keypair uses Example Orders <orders@example.com>.

Configuring GnuPG on the server

GnUPG must be installed, so check with your server admin if you can't find it. Once this has been established a dummy keypair needs to be set up on the server, basically so that you have something to add your real public key to (which we'll do in a moment).

Log into your shell account and type the following...
mkdir .gnupg
chmod 777 .gnupg gpg --gen-key
What we are doing ise stablishing a PGP keyring local to the webserver. It has to have one so you can add your public key from your target machine to it.

You can use anything for the name and sender e-mail address e.g. Example.com website <webserver@example.com>. The keys will then be generated. If GnuPG complains about entropy, you should ssh in a second time and do something that creates lots of I/O e.g du / . On a busy shared webserver this won't be an issue.

You'll then need to import the public key (a text file with a .asc extension) you exported from the machine that'll be doing the decryption. FTP it up (in ASCII mode!) or cut and paste it in. If you're not sure about exporting your ascii armoured public key see this PGP export example using PGPkeys.

At the shell prompt, replacing file.asc with the name of your asc file, type..
gpg --import file.asc gpg --list-keys
You should hopefully see the public key listed.
pub 1024D/FA46F142 2000-11-03 Example.com Orders <orders@example.com> 
Make sure the file permissions are set like so...
 
cd .gnupg chmod 666 trustdb.gpg
chmod 604 secring.gpg
chmod 604 random_seed
chmod 644 pubring.gpg
cd ..
Configuration of the server side of GnuPG is now complete.

Using PGP / GnuPG from within PHP

The following code will do it. It basically sets the home path so GnuPG can find your keyring, and then pipes your data through GnuPG.
<?php

 // Using PHP with PGP.
 // (c) Kelv 2000

 $username = "dummy";       // Your username on the server
 $pgp="/usr/local/bin/gpg"; // path to GnuPG

 // Where the encrypted mail comes from. Dummy address from your keyring.
 $from="Example.com website <website@example.com>";

 // The recipient. This is the imported address from your public key.
 $recp="Example orders <orders@example.com>";

 // The data to be encrypted
 $data="Text that will be encrypted"; 

 $command = 'echo "'.$data.'" | '.$pgp.' -a --always-trust --batch "
 $command.= '--no-secmem-warning -e -u "'.$from.'" -r "'.$recp.'"';
 $oldhome = getEnv("HOME");

 putenv("HOME=/home/$username");
 $result = exec($command, $encrypted, $errorcode);
 putenv("HOME=$oldhome");

 $message = implode("\n", $encrypted); 
 // $message now contains the encrypted data.

 $subject="New order from example.com website";
 $header="From: {$from}";

 mail($recp,$subject,$message,$header);

?>

Hopefully you should now have a PGP encrypted e-mail message you can decrypt on your target machine. Enjoy!

Kelv