Introduction to GPG

OpenPGP is the standard for public-key encryption and digital signatures. GnuPG, usually called GPG, is its most widely used implementation.

This note is a practical introduction to GPG.

Some familiarity with public-key cryptography is helpful here; see also my note on network security.

Introduction

OpenPGP is the protocol-level standard; GPG is the software implementation most people actually use.

At a high level, GPG is used for four things:

  • managing keys
  • encrypting and decrypting files
  • signing and verifying data
  • signing Git commits

This note focuses on command-line usage rather than protocol internals.

Core concepts

An OpenPGP identity is the human-facing label attached to a keypair, usually a name and an email address:

1
Name <[email protected]>

This identity is associated with a public key and a private key.

  • The public key is the part you can share with others. It is used by others to encrypt data to you and to verify your signatures.
  • The private key is the secret part that must remain under your control. It is used to decrypt data encrypted to you and to produce signatures. In practice, this is the only cryptographic secret that really matters for your data privacy: if it is leaked, data encrypted to that key may be decrypted by others; if it is not leaked, then the encrypted data remains protected.
  • The revocation certificate is a special certificate used to declare that a public key should no longer be trusted, for example after loss, compromise, or retirement. It is not as sensitive as the private key, since it cannot be used to decrypt data, but it should still be stored carefully: if someone obtains it, they may be able to revoke your public key, causing communication difficulties.

A key is best identified by its fingerprint. Shorter key IDs are only abbreviated identifiers.

In practice, an OpenPGP private key is usually not a single working key. It often has a small hierarchy:

  • a primary key, often informally called the master key
  • one or more subkeys

The primary key is the root key of the identity. Subkeys are bound to it and are used for actual operations such as encryption, signing, or authentication. For details of key management, see my separate note. I will not discuss that topic further in this post.

Key generation and inspection

Check whether GPG is installed:

1
gpg --version

Generate a key interactively:

1
gpg --full-generate-key

You will be prompted for the key type, key size, expiration time, identity, and passphrase.

A typical output looks like this:

1
2
3
4
pub   rsa3072 2023-07-15 [SC]
7D6950635D1A34200C44E47302753F5D92BA2D0F
uid [ultimate] Yukuan Lu <[email protected]>
sub rsa3072 2023-07-15 [E]

Here:

  • pub is the public primary key
  • sub is a public subkey
  • [SC] means signing and certification
  • [E] means encryption

List public keys:

1
gpg --list-keys

List secret keys:

1
gpg --list-secret-keys --keyid-format LONG

A typical secret-key listing looks like this:

1
2
3
4
sec   rsa3072/02753F5D92BA2D0F 2023-07-15 [SC]
7D6950635D1A34200C44E47302753F5D92BA2D0F
uid [ultimate] Yukuan Lu <[email protected]>
ssb rsa3072/BECE71EA85ACCF78 2023-07-15 [E]

Here:

  • sec is the secret primary key
  • ssb is a secret subkey

Generate a revocation certificate:

1
gpg --output revoke.asc --gen-revoke <KEY-ID>

By default, GPG stores its key material under:

1
~/.gnupg

Import, export, and deletion

Export a public key:

1
gpg --armor --output public.asc --export <KEY-ID>

Export a secret key:

1
gpg --armor --output secret.asc --export-secret-keys <KEY-ID>

Import key material:

1
2
gpg --import public.asc
gpg --import secret.asc

Delete a key pair in the correct order:

1
2
gpg --delete-secret-keys <KEY-ID>
gpg --delete-keys <KEY-ID>

Historically, public keys were often uploaded to keyservers, but a keyserver does not prove authenticity by itself. Fingerprint verification is still necessary.

Useful commands:

1
2
3
gpg --fingerprint <KEY-ID>
gpg --send-keys <KEY-ID>
gpg --search-keys <EMAIL-OR-NAME>

Encryption and signatures

Encrypt a file to a recipient:

1
gpg --recipient <KEY-ID> --output file.gpg --encrypt file

Decrypt:

1
gpg --output file --decrypt file.gpg

If the matching secret key is unavailable, decryption fails.

Sign a file:

1
gpg --sign file.txt

Create a clear-signed file:

1
gpg --clearsign file.txt

Create a detached signature:

1
gpg --armor --detach-sign file.txt

Verify a signature:

1
2
gpg --verify file.txt.asc
gpg --verify file.txt.sig file.txt

Sign and encrypt in one step:

1
2
3
4
5
gpg --local-user <SENDER-KEY-ID> \
--recipient <RECIPIENT-KEY-ID> \
--armor \
--sign \
--encrypt file.txt