Keeping Secrets Safe with GnuPG

Dustin Runnells
Dustin Runnells

GnuPG stands for GNU Privacy Guard, a form of public key cryptography based on the OpenPGP standard. This article will show you how to perform a few essential tasks with GnuPG using PHP and the GnuPG PECL extension. For our purposes, as someone who would like to transmit and receive encrypted messages, you need three keys: your own public key, your own private key, and the public key of the person that you would like to communicate with. Private keys should never be shared, but your own is required to generate an encrypted message. Public keys can and must be distributed. Your public key is required by anyone who wishes to encrypt a message intended for your eyes only or to decrypt a message that you have sent them. The public key cannot be used to forge a signature or decrypt messages meant only for you. GnuPG also serves as a means to verify the authenticity of non-encrypted data via encrypted signatures, but that topic is not covered here. The GnuPG extension discussed here depends on the GnuPG installation on whatever machine you are working with along with the configuration of the user account under which the code will run. The examples provided here are intended to be run from the command line and will interact with the GnuPG environment of the user running them. It should be trivial to extend the concepts here to work from a web script.

Generating Keys

Before you can do anything with GnuPG, you must have a private/public key pair. Though the PECL extension does not let you create these keys right from PHP, you can easily do this from the command line with the gpg command, or a friendly GUI frontend for whatever OS you choose. In Linux, all you need is:
gpg --gen-key
After answering a few easy questions about your identity, selecting a passphrase for use of your private key, and accepting the defaults for everything else, your GnuPG keyring will be generated. The keyring stores your keys and the keys of anyone that you plan to interact with. Once generated, your keyring is automatically populated with your first private/public keys. You should export a copy of both your public and private keys and keep them in a safe place so that you can reuse the same keys in all future interactions with GnuPG. You may also want to consider publishing your public key to a key server to make it available in a safe way to anyone who needs it. More information about GnuPG tools and key servers can be found on the gnupg website.

Exporting Keys

One way to export your GnuPG public key is with PHP. Before you can perform the export however, you must find the key “fingerprint” of your new public key. Every key in your keyring will have a fingerprint that is used as a unique identifier. To list them all, loop through a gnupg_keylistiterator() object:
$iter = new gnupg_keylistiterator();
foreach ($iter as $fingerprint => $user) {
    print "$fingerprint: $usern";
For the keyring of a user named “testuser” on my workstation, the above code results in the following output:
6436010991C352981F95F9A5D5AF916244CD449B: Test User (This is a test account) <>
The key itself is binary data, so to actually encode and print an ASCII version of the public key we need some new code:
$gpg = new gnupg();
$export = $gpg->export("6436010991C352981F95F9A5D5AF916244CD449B");
print $export;
This creates a new gnupg object, and uses the export() method to export the public key corresponding to the provided fingerprint. In my case, the test user’s key is:
Version: GnuPG v1.4.2 (GNU/Linux)

The extension only permits us to export the public key, so if you would like to export your private key in a similar fashion for backup purposes then you’ll need to use the GnuPG tool itself.

Importing Keys

We now have three keys as required for a private exchange. We’ve generated our own public/private keys, and you have the public key for testuser above that we’ll use as a third party public key. To communicate with testuser, we’ll need to get her public key into our keyring. Importing a public key can be done by passing the public key to the import() method:
$gpg = new gnupg();
$info = $gpg->import($keydata);
You can verify that this key has been added to your keyring on the command line with gpg --list-keys and use the gnupg_keylistiterator()
example from earlier to get the fingerprint.

Encrypting Messages

With all of our keys in our keyring, we can encrypt an important message for testuser. The message contains the answer to the question:
Q: How many programmers does it take to change a lightbulb?
We’ll use testuser’s public key to ensure that she will be the only person able to decrypt the answer. The code for encrypting the answer is:
$gpg = new gnupg();
$enc = $gpg->encrypt("A: None, that is a hardware problem!");
print $enc;
We use addencryptkey() to specify which public key to encrypt this message with, which should be the recipient’s key, not the sender’s. In this case it is the public key fingerprint of testuser. Once encrypted, nobody will be able to decrypt the message unless they have testuser’s private key in their keyring… which should be no one other than testuser herself.

Decrypting Messages

From the other side, once testuser receives the message, she can use the code below to decrypt the secret answer:
$gpg = new gnupg();
$plain = $gpg->decrypt($encrypted);
print $plain;
The encrypted message is stored in $encrypted. We create a new gnupg() object, specify which of testuser’s keys should be used for decrypting the message by fingerprint and our private key password, and then print the decrypted message. It is important to mention that decrypting a message will always require the recipient to enter the password that they associated with the private key in addencryptkey()
, except in gnupg v2 where you cannot enter a plain text password in the code – you will be prompted for a password while running this code in the CLI. If you plan to use this function in a web based tool with gnupg v2, you might want to consider excluding the passphrase on the web user’s private key.

In Closing

Now that we know how to encrypt and decrypt with GnuPG, why would you want to in PHP? With SSL you can secure data transmitted between a web server and client, and SSH can be used to secure shell sessions, so why something else? Sometimes you need information to be secure, not only while it is in transit, but also where it is stored and all layers in between. Maybe you need to transmit financial information to a remote location; can you trust system administrators or those who have physical access at the location? Or perhaps a project requires you to transfer data using an insecure protocol, such as FTP. While our simple examples above are useful for transferring encrypted messages, GPG and the gnupg extension can also be used to validate the authenticity of unencrypted messages by the use of signatures. Email is also a notoriously insecure method of communication and messages are easily forged, and though not described in detail here, using encryption and encrypted signatures ensures security and authenticity. I encourage you to further explore the GnuPG tool options and concepts if you’re writing an application that calls for serious data security. Image via Fotolia

Frequently Asked Questions (FAQs) about Keeping Secrets Safe with GnuPG

What is GnuPG and why is it important for data security?

GnuPG, also known as GNU Privacy Guard, is a free software that allows for data encryption and digital signatures. It’s crucial for data security because it provides a way to secure sensitive information from unauthorized access. It uses a method of public key cryptography, where a pair of keys is used – one for encrypting the data (public key) and the other for decrypting it (private key). This ensures that only the intended recipient can access the information, thereby maintaining its confidentiality and integrity.

How do I install and set up GnuPG?

GnuPG can be installed on various operating systems including Windows, MacOS, and Linux. For Windows, you can download Gpg4win, an installer package for Windows, from the official GnuPG website. For MacOS, you can use the GPG Suite. For Linux, GnuPG is usually pre-installed, but if not, it can be installed via the package manager. After installation, you need to generate a key pair. This can be done using the command line interface by entering the command ‘gpg –gen-key’.

How do I encrypt data using GnuPG?

To encrypt data, you need the recipient’s public key. You can encrypt a file using the command ‘gpg -e -r [recipient’s email] [file]’. This will create an encrypted version of the file that can only be decrypted using the recipient’s private key.

How do I decrypt data using GnuPG?

To decrypt a file, you need the private key that corresponds to the public key used for encryption. You can decrypt a file using the command ‘gpg -d [file]’. This will output the decrypted data to the console. If you want to save the decrypted data to a file, you can use the command ‘gpg -o [output file] -d [file]’.

How can I use GnuPG with PHP?

PHP has a GnuPG extension that provides functions for encryption, decryption, signing, and key management. To use it, you need to install the extension and then you can use the provided functions in your PHP code. For example, to encrypt data, you can use the gnupg_encrypt function.

What is a digital signature and how do I create one using GnuPG?

A digital signature is a way to verify the authenticity and integrity of data. It’s created using the sender’s private key and can be verified using the corresponding public key. To create a digital signature for a file using GnuPG, you can use the command ‘gpg –sign [file]’. This will create a signed version of the file.

How do I verify a digital signature using GnuPG?

To verify a digital signature, you need the public key that corresponds to the private key used for signing. You can verify a signature using the command ‘gpg –verify [file]’. This will output whether the signature is valid and who it was signed by.

How do I manage keys in GnuPG?

GnuPG provides various commands for key management. You can list all keys using the command ‘gpg –list-keys’, delete a key using the command ‘gpg –delete-key [key]’, and export a key using the command ‘gpg –export -a [key] > [file]’.

How secure is GnuPG?

GnuPG is considered very secure. It uses strong encryption algorithms and the security mainly depends on the secrecy and strength of your private keys. As long as your private keys are kept secret and are strong (long and random), the encrypted data should be secure.

Can I use GnuPG for email encryption?

Yes, GnuPG can be used for email encryption. Many email clients support GnuPG and can automatically encrypt and decrypt emails. This allows for secure communication, as the emails can only be read by the intended recipient.