gnuPG and Php
Adi Linden
adil@adis.on.ca
Tue Feb 25 23:27:02 2003
> I can use it from command line, but would like either a cgi or php way
> to use gnuPG from a webpage.
I am still new to gnupg but perhaps I can help. I read some info on it,
one suggested piping the data to encrypt into gpg via stdin using
backticks:
`echo $data | gpg ....`
Unfortunatly many nasty things happened when I did that, because i was
sending a xml form to gpg. I suspect quoting got mixed up. Instead I used
popen to write the data to gpg and output the data to a temporary file. I
figured that even in scenary where the site is hosted on a shered server
there is little risk in writing the ascii armored output of gpg to a file,
since the webserver only has the public key but no private key.
Here's the php function I came up with. The global variables
$email_recipients, $gpg_path and $gpg_home need to be set prior to calling
this. $email_recipients is an array of recipient email addresses,
$gpg_path is the path and name of gpg (i.e. /usr/bin/gpg) and $gpg_home is
the directory containing the key ring.
/*
* enc_gpg -- encode data using gpg
* To make this work I open a pipe to gpg and write the output
* to a file. This should be safe since the private key to
* decrypt the file is nowhere on the server.
*
* &$data - data is modified only on success
* returns - true on success
*/
function enc_gpg(&$data)
{
global $email_recipients;
global $gpg_path, $gpg_home;
/* Create a temporary file name for gpg */
$tmpfile = '/tmp/phpbasket_' . md5(uniqid(time()));
/* Build the command line for gpg */
$cmd = $gpg_path . ' --always-trust --batch --no-tty -e -a ';
$cmd .= ' --no-secmem-warning --homedir ' . $gpg_home;
$cmd .= ' -o ' . $tmpfile;
foreach ($email_recipients as $r) {
$cmd .= ' -r ' . $r;
}
/* Pipe data to gpg */
$fp = (popen($cmd, 'w'));
if (!$fp) {
unlink($tmpfile);
return false;
}
fwrite($fp, $data);
pclose($fp);
/* Read data from temporary file */
$fp = (fopen($tmpfile, 'r'));
if (!$fp) {
unlink($tmpfile);
return false;
}
$res = fread($fp, filesize($tmpfile));
fclose($fp);
unlink($tmpfile);
/* Verify we have valid encrypted data */
if(ereg("-----BEGIN PGP MESSAGE-----.*-----END PGP MESSAGE-----", $res)) {
$data = $res;
return true;
}
return false;
}
Hope this is of use...
Adi