LJ Archive

GnuPG Hacks

Tony Stieber

Issue #143, March 2006

GnuPG does a lot more than just encrypt and decrypt e-mail and attachments.

Have you wondered about using cryptography, but found it too confusing? Are complicated software packages, passphrases, keys, key rings, certificates and fingerprints too daunting?

You don't need all that. With no prior experience and nothing to remember, GnuPG can do basic and immediately useful cryptography. GnuPG even may be installed on your Linux system already.

GnuPG and OpenPGP

The GnuPG is the GNU Project's implementation of the OpenPGP standard. Also known as the Gnu Privacy Guard, it is a sophisticated public key cryptosystem with more than 70 command-line options, plus an internal command-line and menu environment. It has been ported to several operating systems and has precompiled binaries available from the GnuPG Web site (see the on-line Resources). Like all GNU software, it can be used freely under the GNU General Public License.

The OpenPGP standard, RFC 2440, is based on the Pretty Good Privacy system developed by Phil Zimmermann in 1991. OpenPGP is also the basis for commercial products on even more operating systems. An OpenPGP system is the most common file encryption system you will encounter.

Getting Started

First, let's begin with some GnuPG features that don't need a passphrase. After that, we'll choose a passphrase and use it to encrypt something. Note that GnuPG is the name of the software, but the name of the command is gpg.

Make sure GnuPG is installed and in your path:

gpg --version

You should get something like this:

gpg (GnuPG) 1.4.1
Copyright (C) 2005 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to
redistribute it under certain conditions.
See the file COPYING for details.

Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512
Compression: Uncompressed, ZIP, ZLIB, BZIP2

The version number, date and other details may vary. The examples shown in this article should work for most current and future versions of GnuPG.

Now, type:

gpg /dev/null

You might get something like this:

gpg: /home/you/.gnupg: directory created
gpg: new configuration file `/home/you/.gnupg/gpg.conf'
 ↪created
gpg: WARNING: options in `/home/you/.gnupg/gpg.conf'
 ↪are not yet active during this run
gpg: keyring `/home/you/.gnupg/secring.gpg' created
gpg: keyring `/home/you/.gnupg/pubring.gpg' created
gpg: processing message failed: eof

This is perfectly normal the first time you run GnuPG. If it doesn't happen, it simply means you've run GnuPG before, or your .gnupg directory already exists.

Binary File Shields

Most e-mail programs support file attachments, but command-line e-mail programs, such as /bin/mail, don't. Sometimes it's more convenient to keep all the data in the message body. But binary files must be ASCII-encoded to prevent them from being corrupted in transit.

You may have tried to use uuencode and found it confusing or that it didn't work. Not all systems have a command-line MIME encoder. However, GnuPG has an ASCII-encoding option very similar to MIME, but without all the complexity, overhead and features.

To wrap a file in PGP ASCII armor, type:


$ gpg --enarmor < filename.bin > filename.txt

To unwrap a file already in PGP ASCII armor, type:


$ gpg --dearmor < filename.txt > filename.bin

Warning: despite the name, the OpenPGP ASCII armor has absolutely no security. If you do want security and data compression, see the Quick and Clean Encryption section below and use a good passphrase.

Better Checksums

Do you suspect a file you just received is corrupted? Traditionally, the sum or cksum command is run over the file before and after it was sent and the outputs are compared. But there are three different incompatible versions of these commands, and even the same version can produce completely different output on different machines due to processor endian issues. Even worse, sometimes they won't even detect corrupted files. By chance alone, even when they are compatible, they sometimes will produce the same output for different files. The 32-bit output of the sum and cksum commands is simply too small for reliability, much less security. The popular SSH v1 CRC-32 compensation attack is the same vulnerability.

You could use md5sum instead, but there are different versions of this command. Each version has slight differences in formatting of filenames, whitespace and hexadecimal case. These differences in format prevent diff from running cleanly. In addition, there are known security vulnerabilities in the MD5 hash algorithm used by md5sum. And, sometimes md5sum isn't even installed.

GnuPG avoids these problems, because it produces the same output regardless of operating system or processor architecture. GnuPG also supports newer and more secure algorithms:

$ gpg --print-md sha1 filename
filename: E83A 42B9 BC84 31A6 6450  99BE 50B6 341A 35D3 DCEB

It also will take multiple files:

$ gpg --print-md sha1 *.txt
test.txt: E0D6 3F44 4253 CED5 9205  4047 4AA6 4E0F FD0F 130D
test2.txt: 32AC 34F9 B7AF 1972 C015  E5EE 456E 89BD CC3C 7246

If you still need MD5, that's available too:

$ gpg --print-md md5 filename
filename: 26 E9 85 5F 8A D6 A5 90  6F EA 12 12 83 C7 29 C4

The more recent GnuPG versions also support much more secure hash algorithms, such as SHA-512:

$ gpg --print-md sha512 filename
filename: FC37410D 9336DD60 22AEB6A2 A42E82F1 2EA3470D 4982E958 B35C14A0
          CF381CD2 3C4CBA35 BE5F11CB 05505ED2 DBF1C7A0 397EFF75 007FAEBB
          30B43B30 6514990D

By the way, you can validate these --print-md examples by creating a file called filename containing the single line: The Linux Journal.

Your hash values should have exactly the same hexadecimal value as those in this article if the contents of the file is the same.

Quick and Clean Encryption

Want to encrypt a file, but don't know where to start? Here's a quick and clean introduction to file encryption using GnuPG:

$ gpg -c test.txt
Enter passphrase:
Repeat passphrase:

When encrypting, GnuPG asks for a passphrase twice, just like when you set a new password. The new encrypted file has the same name, but with the extension .gpg added. The original file is left intact.

The -c stands for conventional encryption, also known as symmetric encryption. Normally, GnuPG defaults to public key encryption, but we haven't generated or loaded any public keys, so for now we have to stay with conventional.

This type of encryption is most useful only if you want to decrypt your files, but you don't trust where your files are stored. For example, easily lost or stolen storage can be protected with this type of encryption. This type of encryption is especially useful for off-site backups.

To extract the encrypted file, simply type:

$ gpg filename.gpg

GnuPG automatically detects that the file is encrypted with a passphrase and asks for that passphrase. Then it writes the decrypted data to a file with the same name but without the .gpg extension. As with encrypting, the encrypted file is left intact. If you want the output file to be written to a different filename, use standard redirection, exactly as with the --dearmor example. Note that both input and output redirection must be used, or GnuPG becomes confused:


$ gpg < filename.gpg > filename.txt

If you want someone else to decrypt the file, you have to tell this person the passphrase without leaking the passphrase to anyone else. A simple and straightforward way to do this is in person. That might seem not very useful, as the original file also could be given in person. But that passphrase can now be reused safely multiple times on different files in the future. Just like passwords, however, passphrases should be changed regularly. Never reuse a passphrase with other people, unless you want them to decrypt all of the files you ever encrypted with that passphrase.

Note: this warning is normal when using passphrase encryption in GnuPG. This can be avoided with public key encryption:

gpg: WARNING: message was not integrity protected

Passphrases

The passphrase is a secret that keeps the other secrets, which makes it the most important part of GnuPG security. Unfortunately, in practice, passphrases are also the weak part. This is because creating good passphrases is difficult, and remembering them is even more difficult.

I highly recommend Diceware, but if it doesn't appeal to you, take a look at the Wikipedia article (see Resources) or the passphrase Web pages recommended by your favorite Web search engine.

Regardless of what method you choose, a simple guide to passphrase security is that longer is usually better (Table 1).

Table 1. Password and passphrase strengths compared with estimated time to crack.

TypeLengthBitsTotal BitsTime to Crack
Single word of any language8 characters2424Seconds
Random mono-case letters8 characters4.737Minutes
Random mono-case letters16 characters4.775Decades
base64 [A-Za-z0-9+/=]10 characters660Months
base64 [A-Za-z0-9+/=]20 characters6120Uncrackable?
Completely random printable6 characters6.540Minutes
Completely random printable8 characters6.552Hours
Completely random printable12 characters6.578Decades
Completely random printable15 characters6.597Centuries
Completely random printable20 characters6.5130Uncrackable?
Diceware passphrase2 words12.926Seconds
Diceware passphrase4 words12.951Hours
Diceware passphrase6 words12.978Decades
Diceware passphrase8 words12.9120Uncrackable?

The time estimates in Table 1 are wide, because money and time can be traded evenly. Computing power keeps getting cheaper, so time to crack keeps getting shorter. Cracking costs start at free and go up.

If you cannot remember a GnuPG passphrase, the data encrypted with that passphrase is probably gone forever. There are no known back doors in GnuPG nor any way to recover a lost passphrase short of guessing. How long it takes depends on how good the passphrase was. A good 20-character passphrase could take billions of years to guess, even using all current and future computers.

Generate a Passphrase

Here's a quick hack for generating a very secure passphrase using GnuPG itself. The passphrase will not be easy to remember or type, but it will be very secure. The hack generates 16 random binary bytes using GnuPG then converts them to base64, again using GnuPG. The final sed command strips out the headers leaving a single line that can be used as a passphrase:

gpg --gen-random 1 16 | gpg --enarmor | sed -n 5p

Encrypted Tarballs

Instead of using gzip to compress tarballs, use GnuPG. The tarballs will end up being about the same size, but they also will be encrypted. By the way, don't bother trying to gzip or otherwise compress any encrypted files. Encrypted data is usually incompressible. This is because data compression and encryption are closely related mathematically. Because of this, most cryptosystems, GnuPG included, automatically compress before encryption. There is also a slight gain in security by compressing.

You will be prompted for a passphrase twice, just like when encrypting before:

tar -cf - these files here | gpg -c > these-files-here.tgp

To extract the files, enter the password entered above:


gpg < these-files-here.tgp  | tar -xvf -

Automating GnuPG

If you want to use GnuPG in a script and don't want to be prompted for the passphrase, put the passphrase in a file called passphrase.txt, and use this to encrypt:


[$ cat passphrase.txt | gpg --passphrase-fd 0 -c < filename.txt > filename.gpg

Note: decrypting is nearly identical, simply drop the -c and switch the files around:


$ cat passphrase.txt | gpg --passphrase-fd 0 < filename.gpg >
filename.txt

If you're going to e-mail the encrypted file, perhaps for off-site backup, add the -a option to turn on ASCII armor. The net effect is the same thing as --enarmor used earlier, but it includes encryption. This also produces smaller files than uuencoding or MIME, because by default, GnuPG compresses data before encryption.

To finish off the hack, we also mail the encrypted file at the same time. Note the use of -o - to force GnuPG's output to stdout:

$ cat passphrase.txt | gpg --passphrase-fd 0 -ac -o - filename.txt | mail user@example.com

By the way, putting the passphrase in a file can be extremely dangerous. Anyone who obtains a copy of that passphrase file can then decrypt any file it has ever encrypted. Someone even could create new files with the same passphrase, resulting in secure and undetectable forgery. Make sure your passphrase file, indeed the entire computer, has the security you expect.

Automating tasks inherently requires cutting humans out of the loop, so this security weakness is difficult to avoid. However, GnuPG can help even here by using public key encryption.

GnuPG Troublehacking

Do you have an OpenPGP-encrypted file, but no key ring and no idea what to do with it? Perhaps someone sent you an encrypted file and assumed you would know what to do. Maybe he or she doesn't know what to do either.

If the file has either a .pgp or .gpg extension, you can try decrypting it with GnuPG. Also, check the file with a text editor to see if it contains something like this:

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.2.5 (GNU/Linux)

jA0EAwMCwg21r1fAW+5gyS0KR/bkeI8qPwwQo/NOaFL2LMXEYZEV9E7PBLjjGm7Y
DGG4QnWD5HSNOvdaqXg=
=j5Jy
-----END PGP MESSAGE-----

If it does, it's an ASCII-armored PGP-encrypted file.

This particular file is a real encrypted file containing the same value as used in the --print-md examples above and is encrypted with a passphrase of the same value.

Simply running GnuPG on an unknown file produces some useful information. If it prompts you for a passphrase, you'll need to get (or guess) the passphrase used to encrypt the file:

gpg unknown_file

If it's not an OpenPGP file, you'll get something like this:

gpg: no valid OpenPGP data found.
gpg: processing message failed: eof

If you get something else, however, maybe the file is encrypted with a public key that you don't have. The file also could be corrupted. A common mistake is to send binary files through e-mail or FTP transfer in ASCII mode.

GnuPG has a special diagnostic option to help troubleshoot these problems. The OpenPGP message format is internally formatted as packets; the --list-packets option dumps out information about those packets:

gpg --list-packets unknown_file.gpg

In addition to the standard information, this option also prints the full key ID of the public key that the file is encrypted with, if any, and what algorithms were used. It could be that the file was encrypted with a PGP 2.x public, sometimes called a legacy key. PGP 2.x predates the OpenPGP standard, so the standard GnuPG cannot decrypt it. Most PGP implementations made in the past several years are usually OpenPGP-compatible, so merely asking the sender to generate a compatible OpenPGP-encrypted file should do the trick.

There also are several different cryptographic algorithms supported by OpenPGP. Most have only some of these algorithms implementationally. Use gpg --version to see what might be missing.

Details on the packet format, such as the internal algorithm numbers, can be found in the OpenPGP standard RFC 2440.

Table 2. A short list of GnuPG options mentioned in the article.

Short OptionLong OptionDescription
 --versionVersion and algorithm information
 --helpHelp
-a--armorTurn on ASCII encoding when encrypting
 --enarmorInput binary, output ASCII
 --dearmorInput ASCII, output binary
 --print-md HASHPrint a message digest using the specified HASH
-c--symmetricConventional symmetric encryption with a passphrase
-o--outputSpecify a particular output file, use - for stdout

GnuPG mostly uses long command-line options, but some options also have short single-letter options from the original PGP. For example, -v is --verbose, not --version.

Learning More

There are several good introductions to using the more common features of GnuPG, such as the GnuPG MiniHOWTO by Brenno de Winter at the GnuPG Web site (see Resources). They explain in detail how to use the more common public key cryptography features of GnuPG.

The GnuPG mailing lists are also very useful and fully archived on the GnuPG Web site. Werner Koch, the GnuPG lead developer, frequently posts to the mailing lists and is of invaluable help.

Resources for this article: /article/8743.

Tony Stieber is an information security professional specializing in UNIX systems, cryptology and physical security. He has been learning Linux since 1999, UNIX since 1987 and computers since before 1980. He does not yet know what the next decade will offer.

LJ Archive