Keeping Secrets Safe with GnuPG

Share this article

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:
<?php
$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) <test@example.com>
The key itself is binary data, so to actually encode and print an ASCII version of the public key we need some new code:
<?php
$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:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2 (GNU/Linux)

mQGiBFDP4+cRBACupVdbSBVa5wLjKFoELiS9IunzQA6hj2P1jCYmXtwSPwvvrXRX
LqhpkmXmWrHvo+4WW8aDjI2csuh8z4gNB+YGkaB3iKZxyhdazKco0R1BU7fjPrUn
4iqVqkpaixcdMVDPkjjBTJDEdjxWWieErSzbzkjy8wuTJR+lAVFWTcuTOwCg9WAg
bLwpPIlcULQ+D/l3sLt2AaED/jgdcTvMsVG96xZGWT9bewl/HVX+2ZpCWIkbE34E
AABS8c9hwNEz3QvkEqoxcf5sC8ujtvTf3Gky4E6h4KZrpCZuZ8kFRQiAhqP6XwNi
8jJM0BK8ooYPFP4UsfRQImc4XczL/njtwpwJ8wX2UOb7oglJB5acMulvzpD4cRvK
FkqIA/9NzGFExUeJeJ8b6GC17KDOIHfBwlrcGvc85c574fUVekV9jGGaAzl6i89O
OIWQCELH9s8quTA23tDeMcHRwUMHAYxh7lf2stoJmwz0IySpUCkmxcUhB5TIzBOB
jHifGAlJKby6gNJhlvghTxXlVGsQiM14JLJo2+hS2qMc17vp77QyVGVzdCBVc2Vy
IChUaGlzIGlzIGEgdGVzdCBhY2NvdW50KSA8dGVzdEB0ZXN0LmNvbT6IYAQTEQIA
IAUCUM/j5wIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJENWvkWJEzUSb6iIA
nRhCMJ3CN+1QXSD2zAtsoWgVebqZAKDLp1636WZ3XZAIVOlHBnpMTfcdA7kCDQRQ
z+PwEAgAkRnVYvmbpkGCCU8T56Wh2+jMA5GVPbPuyqmprfvgrt7yp9EEXfXRrGVA
KYMbFDU4+Vdc2U9Wm/T6P7McvI3dJARWOD6NeqOh+k6yTYxH+qznsU2d/7+Vugfx
zxVXtllhpnyWc5AlAr6yo98UdjO+q5RNM3fzSdjHth+MCJqEBfkyTui2VN9odnnS
IkDFHJyVcaUfQ580RpLWllwAC3+Urntc02S6xxEr03fKIe/wuhXC9gpG5lWu3hyj
k0PlsSh55w5gb4zF3Q2yDbToAuvSg1My0ytIPddmjjBx8gs4PCnB+48R52jsT/uI
Ju6j83Ddy1Ph1cnalChIpMit2Hm40wADBQf+J+NRhzLByj3YRsRK9ohZ0dm1+sMU
S86Xv676IQMgTzohFCAicnFZtTJx6N35pox/azOOGxAoof79TPv1r897bysAXjmu
qjW2mMpAfhnNY18Wf2SB+R7oYsID/z4fOQltyX54z8Fi40OO6UtI1X3Lh4KGzhUK
AnkgVeYGxupiK2HHtxeknEiKuAY+RXiQRYIC8YgAZboKqbWt8WVSMwctLbtRgXQC
VlkcZzwPk+mPocxYcnID+mZgIpwX0/+Zs4OOlyrf1k1oI6zQA7tJ+etGugtee78j
e8gub9CYvyCJMFM3pI5OEKC9BRSjPjgSw/6kQEc4bHP1Bn4WqPgh2d61Q4hJBBgR
AgAJBQJQz+PwAhsMAAoJENWvkWJEzUSbAhYAoKnL/nGFmJejtoPdws+QRW95VECn
AJ4yFFV1axpTDbIClQQTerJS7xpxjg==
=g/FY
-----END PGP PUBLIC KEY BLOCK-----
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:
<?php
$keydata = "FULL PUBLIC KEY FROM ABOVE";
$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:
<?php
$gpg = new gnupg();
$gpg->addencryptkey("6436010991C352981F95F9A5D5AF916244CD449B");
$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:
<?php
$encrypted = "THE UNREADABLE ENCRYPTED MESSAGE SHOULD BE PASTED HERE";
$gpg = new gnupg();
$gpg->adddecryptkey("6436010991C352981F95F9A5D5AF916244CD449B","test1234");
$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.

Dustin RunnellsDustin Runnells
View Author

Dustin Runnells is a passionate technology enthusiast in Rochester, NY, with a special interest in Linux and social media. While juggling a full-time job as a professional programmer at a real company and being a loving husband and father of three, Dustin fills whatever time he has left tinkering on his personal projects. Dustin is MySQL Core Certified, LPI1 Certified, and a Zend Certified Engineer.

Intermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week