Link to home
Start Free TrialLog in
Avatar of Julian Matz
Julian MatzFlag for Ireland

asked on

PHP and GnuPG Encryption

Hello!

I have the following:

1. a html form on a website where users enter data
2. a php script which processes the data and sends it to an email recipient

What I need is:

one or two strings of data from the form to be encrypted using a GnuPG public key.

So, in fact I need the php script to send two emails. One with the unencrypted form data and a second with the encrypted data.

How can I get php to encrypt these strings for me??

Many thanks for your help!!!

GnuPG can be found here: http://www.gnupg.org/
ASKER CERTIFIED SOLUTION
Avatar of Joseph Melnick
Joseph Melnick
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Julian Matz

ASKER

Hi Joseph,

Thanks for that. I tried to install the package with PEAR and I also installed libgpg-error and gpgme library but somehow I don't think it worked out...

Is there no easier way to do this? All I really need is to be able to encrypt a string using a certain pub key...

I thought it might work using something like
$cmd = "$gpg --homedir /home/username/.gnupg...."

Sorry, I'm not very advanced with PHP yet...
Sending the unencrypted version of the email could be read by anyone so why military strength public key encryption for the second email?

the module allows you to interface with gnupg using an object oriented php package.

The quick and dirty method that you suggest might also work to create a file that can be attached to the email with file_get_contents() php function.

Joseph Melnick (jmelnick)

I do not need to send 2 copies of the same email... When the html form data is submitted it will contain some sensitive information so I need to encrypt this data before sending it. The rest of the information does not need to be encrypted. So, basically I need to send only part of the data encrypted in a separate email. I hope this makes sense...

If you're familiar with the package you mentioned maybe I could run through the steps I took to install it???
1. Installed libgpg-error (from source - ./configure, make, make install)
2. Installed gpgme (from source)
3. Installed the PECL GnuPG package using PEAR ($ pear install gnupg)

When running a test via web browser I got the error message "Fatal error: Class 'gnupg' not found...".
I presumed that there was an error loading the module and I couldn't find any documentation that could help me solve this problem...

I found this on the Zend website (http://www.zend.com/zend/tut/tutorial-brogdon.php):

<?php
    $gpg = '/usr/bin/gpg';
    $recipient = 'john@doe.com';
    $encrypted_message =  base64_encode(shell_exec("echo $argv[1] | $gpg -e -r $recipient"));
    mail('john@doe.net',  
         'Your Encrypted Message',  
         $enrypted_message);
?>

Do you think this would work without the PECL package?

Thanks for your help...
Ok, I just realised that having shell_exec() enabled is a pretty big security threat...
Unfortunately yes -- jmelnick
Do you know what I might have done wrong with the PECL package?
if the package is in the correct place then not sure too many possibilities.


Did you install per instructions in readme?

http://www.php.net/manual/en/install.pecl.php

Joseph Melnick (jmelnick)
Yes, I tried to follow the instructions as best I could.
I downloaded and installed libgpg-error and gpgme source from http://www.gnupg.org/(en)/download/index.html
Then I installed the PECL package using the pear command ($ pear install gnupg)

I got some error messages at the start before I installed libgpg-error and gpgme. I also had to install php5-cli using apt-get.

I understand I have to load the module. I presume this is to be done in php.ini. Do you know the correct way of loading it??
Also, could you tell me what directory this would be referring to ??

/your/phpsrcdir/ext

What is the phpscrdir?
Ok, I found gnupg.so in this path:
/usr/lib/php/extensions/no-debug-non-zts-20041030/gnupg.so
so I had to set it in php.ini and I think I finally managed to load the module.

Now I think it seems to be working but I'd like to test it. I ran some tests but not getting any wiser... Could you give me an example function so I can test this? Maybe an example for gnupg_keyinfo(). I've tried it using the examples in the php manual but just returned a blank page... I'd appreciate your help...

- Julian
Hello julianmatz,

I'll find something for you.

Joseph Melnick (jmelnick)
Hello Julian,

I assume that you have created your own key on the server using the command: gpg --gen-key

use: gpg --fingerprint    to capture your fingerprint.

Fingerprint for my personal key:
D9757523C8729ADB9181CCE5544DED1BFE4F1800

The following will echo encoded string.

<?php
$res = gnupg_init();
gnupg_addencryptkey($res,"D9757523C8729ADB9181CCE5544DED1BFE4F1800");
$enc = gnupg_encrypt($res, "just a test");
echo $enc;
?>

Joseph


Hi Joseph,

Thanks for your help. I appreciate it.

I created a keypair using gnupg and enigmail on my computer. I exported the pubkey to a file and stored it on the server. To add the key to my keyring I used the command
$ gpg --import a filename

That worked out grand and I used
$ gpg --fingerprint
to get the fingerprint

Then I put the code you mentioned into a php file (replaced the fingerprint) and called it in my browser. I just got a blank page however.

I wasn't sure which keyring it tried to access. I know that the default is
~./.gnupg/ and I even tried changing this using the putenv() function.

In the end I thought if I simply use the gnupg_import function that the key would be imported to the correct keyring, so this is what I did:

=================================
<?php
$keydata = '-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2 (MingW32)
Comment: GnuPT 2.7.2

mQGiBEPH3nkRBACV6bh7uNY3TD3i768G7dT236hKigtyrmcxtF/oUxl0JXRvbVYH
0v9CaDdCYF4zRs3YZBezMQoJJgjIGq57J0SMrJQ/y51Uluz5L4yPwF5H3vQZYcMi
b+......
=Kc5c
-----END PGP PUBLIC KEY BLOCK-----
';

$res = gnupg_init();
$info = gnupg_import($res,$keydata);
print_r($info);
?>
=================================

In this example I shortened the key block to save space...

The result I got from this was:

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

which suggests to me that the key wasn't imported for some reason???
I must be doing something wrong...

- Julian
Hi Joseph,

I managed to figure it out. It seems to be working now. Took me some time to figure out but it was an issue with file permissions. Thank you for pointing out the PHP extension to me... This was quite a big project for me and had been working on it for a couple of months...

For reference, here are the steps I took to make it work:

1. Created a new directory called '/pubkeys/.gnupg
$ mkdir /pubkeys/.gnupg

2. Changed ownership for the directory to user running web server (www-data)
$ chown -R www-data /pubkeys
$ chgrp  -R www-data /pubkeys

3. Edited httpd.conf for virtual directory to include /pubkeys in open_basedir
<Directory "/var/www/web1">
    php_admin_value open_basedir /pubkeys/
</Directory>

4. Imported the public keys using a php script so not to mess up the file and ownership permissions

<?php
 $gpg = new gnupg();

 $keyring = "/pubkeys/.gnupg";
 putenv("GNUPGHOME=$keyring"); // to change the default GnuPG keyring home directory (--homedir)

 $keyblock = "[keyblock]";

 $result = $gpg -> import($keyblock);
 print_r($result);

?>