Floating Octothorpe

Working with GPG

The GNU Privacy Guard (GnuPG) is a free open source implementation of the OpenPGP standard. There is a good chance you already have the command line tool (gpg) installed, if not packages can be found on the GnuPG download page.

Symmetric encryption

A very simple way to encrypt data is with symmetric encryption, this can be done with the -c or --symmetric options:

$ echo 'secret data' > somefile.txt
$ gpg -c somefile.txt
Enter passphrase:
Repeat passphrase:

After a passphrase has been entered and verified GnuPG will encrypt the file and write the cipher text to an new file ending in .gpg:

$ file somefile.txt.gpg
somefile.txt.gpg: GPG symmetrically encrypted data (CAST5 cipher)

The data can then be decrypted with the same passphrase:

$ gpg somefile.txt.gpg
gpg: CAST5 encrypted data
Enter passphrase:
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected
$ cat somefile.txt
secret data

Asymmetric encryption

Generating a new key pair

If you want to use asymmetric encryption, the first thing you will need to do is generate a new key pair. This can be done with the --gen-key option:

$ gpg --gen-key
gpg (GnuPG) 1.4.19; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

When running the command you will be prompted for they kind of key(s) you want to create. For most people RSA should be fine (this is the algorithm recommended by RFC 4880):

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection?

You will also be prompted for how long the key should be, by default 2048 should be fine. A rationale for this can be found on the GnuPG FAQ:

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits

You when then need to specify how long the key should be valid for:

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)

The user ID associated with the key:

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <[email protected]>"

Real name: Example User
Email address: [email protected]
You selected this USER-ID:
    "Example User <[email protected]>"

And finally a passphrase to encrypt the private key. There is no limit on passphrase length, and from a security perspective it's worth using a long passphrase, as it's the only protection you have if you're private key file is compromised:

You need a Passphrase to protect your secret key.

Enter passphrase:

If everything goes correctly your keys should now be saved to ~/.gnupg/:

$ ls -1 ~/.gnupg/

You can also verify keys have been generated using the --list-keys option:

$ gpg --list-keys
pub   2048R/5B5D90CE 2017-08-10
uid                  Example User <[email protected]>
sub   2048R/8CE63902 2017-08-10

Revocation certificate

Although not strictly necessary, it's a good idea to pre-generate a revocation certificate. In the event that you're key pair is either lost or compromised the revocation certificate can be published to invalidate your public key. This can be done with a command similar to the following:

gpg --output revoke_key.asc --gen-revoke "Example User <[email protected]>"

Note: the generated certificate should be stored offline, not with your private key!

Exporting your public key

The --export option can be used to export your public key:

$ gpg --armor --export "Example User <[email protected]>"
Version: GnuPG v1


Note: --armor is used to base64 encode the public key.

Your public key can be used by anybody to encrypt data, which you can then decrypt with the corresponding private key. There are a few different ways to distribute your public key:

Importing public keys

To send encrypted messages to someone you first need to get a copy of their public key. The --import option can then be used to import the key:

$ gpg --import alice_example.com.key
gpg: key 4264D469: public key "Alice <[email protected]>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

Encrypting and decrypting messages

Once you have a public key, you can use the --encrypt option to encrypt data:

$ echo 'secret message' > message.txt
$ gpg --output message.gpg --encrypt --recipient [email protected] message.txt
$ file message.gpg
message.gpg: PGP RSA encrypted session key - keyid: 3E6EA063 270B658 RSA (Encrypt or Sign) 2048b .

The --decrypt option can then be used to decrypt the message with the corresponding private key:

$ gpg --output message.txt --decrypt message.gpg

You need a passphrase to unlock the secret key for
user: "Alice <[email protected]>"
2048-bit RSA key, ID 58B67002, created 2017-08-11 (main key ID 4264D469)

gpg: encrypted with 2048-bit RSA key, ID 58B67002, created 2017-08-11
      "Alice <[email protected]>"

$ cat message.txt
secret message

Signing messages and verifying the author

As well as encrypting messages and data, it's also useful to be able to verify a message was sent from the person you expect. This can be done by signing a file with the --sign option:

$ cat message.txt
This is Alice...

$ echo 'This is Alice...' > message.txt

$ gpg --armor --output message.txt.sig --sign message.txt

You need a passphrase to unlock the secret key for
user: "Alice <[email protected]>"
2048-bit RSA key, ID 4264D469, created 2017-08-11

$ file message.txt.sig
message.txt.sig: PGP message Compressed Data (old)

The signed message can then be verified using the --verify option:

$ gpg --verify message.txt.sig
gpg: Signature made Fri, Aug 11, 2017  5:54:36 PM GMTDT using RSA key ID 4264D469
gpg: Good signature from "Alice <[email protected]>"
Primary key fingerprint: D401 7604 FC42 9C4A C5A0  FD4D E94D B885 4264 D469

If the --verify option is omitted GnuPG will also extract the message after verifying the signature:

$ gpg message.txt.sig
gpg: Signature made Fri, Aug 11, 2017  5:54:36 PM GMTDT using RSA key ID 4264D469
gpg: Good signature from "Alice <[email protected]>"
Primary key fingerprint: D401 7604 FC42 9C4A C5A0  FD4D E94D B885 4264 D469

$ cat message.txt
This is Alice...

Clear-text signatures

For plain text such as emails, it's often easier using the --clearsign option. If this option is used the message can easily be read, without first having to extract the message from the signed file:

$ gpg --clearsign message.txt

You need a passphrase to unlock the secret key for
user: "Example User <[email protected]>"
2048-bit RSA key, ID 5B5D90CE, created 2017-08-10

$ cat message.txt.asc
Hash: SHA1

This message is signed, but can be read without the gpg command
Version: GnuPG v1


Using a separate signature

Alternatively the --detacted option can be used to create the signature in a separate file:

$ gpg --armor --detach-sign data

You need a passphrase to unlock the secret key for
user: "Example User <[email protected]>"
2048-bit RSA key, ID 5B5D90CE, created 2017-08-10

$ ls -lh data data.asc
-rw-r--r-- 1 user 197121 10M Aug 11 18:16 data
-rw-r--r-- 1 user 197121 473 Aug 11 18:23 data.asc

This is particularly useful for large files such as ISOs.

Further reading

If you need more GnuPG information the GnuPG documentation is a good place to start.