PHP and GnuPG Encryption


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:
LVL 21
Julian MatzJoint ChairpersonAsked:
Who is Participating?
Joseph MelnickSenior Software Developer - Pharmacy ApplicationsCommented:
Hello  julianmatz,

there is a PECL Package for this purpose:

Take a look.

Joseph Melnick (jmelnick)
Julian MatzJoint ChairpersonAuthor Commented:
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...
Joseph MelnickSenior Software Developer - Pharmacy ApplicationsCommented:
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)

Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Julian MatzJoint ChairpersonAuthor Commented:
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 (

    $gpg = '/usr/bin/gpg';
    $recipient = '';
    $encrypted_message =  base64_encode(shell_exec("echo $argv[1] | $gpg -e -r $recipient"));
         'Your Encrypted Message',  

Do you think this would work without the PECL package?

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

Did you install per instructions in readme?

Joseph Melnick (jmelnick)
Julian MatzJoint ChairpersonAuthor Commented:
Yes, I tried to follow the instructions as best I could.
I downloaded and installed libgpg-error and gpgme source from
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??
Julian MatzJoint ChairpersonAuthor Commented:
Also, could you tell me what directory this would be referring to ??


What is the phpscrdir?
Julian MatzJoint ChairpersonAuthor Commented:
Ok, I found in this path:
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
Joseph MelnickSenior Software Developer - Pharmacy ApplicationsCommented:
Hello julianmatz,

I'll find something for you.

Joseph Melnick (jmelnick)
Joseph MelnickSenior Software Developer - Pharmacy ApplicationsCommented:
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:

The following will echo encoded string.

$res = gnupg_init();
$enc = gnupg_encrypt($res, "just a test");
echo $enc;


Julian MatzJoint ChairpersonAuthor Commented:
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:

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


$res = gnupg_init();
$info = gnupg_import($res,$keydata);

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
Julian MatzJoint ChairpersonAuthor Commented:
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/

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

 $gpg = new gnupg();

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

 $keyblock = "[keyblock]";

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

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.