How GnuPG Works

I first used GnuPG 21 years ago, to securely communicate from Germany with my US-based girlfriend at the time (who became my wife of by now 17 years). That was before the web (I discovered it in December 1993), and connectivity was over a modem, “somewhere” in the company that paid my salary. This modem exchanged e-mail once every 24 hours I believe, and disconnected as soon as it was done for the day. There were only rumors as to who actually operated that line, and because of that, encryption seemed like a good idea.

But there were always some points I didn’t understand, and so today, I sat down to investigate. Here are my notes from reviewing the GnuPG manual, in the hope that clarifies for others, too.

  • Of course, each GPG user has a key pair, meaning two cryptographically (cryptically? :-)) related large numbers, one called a public key and one a private key.
  • If you have something to encrypt (the plaintext), you take the public key, apply the algorithm, and gibberish results (the ciphertext). To decrypt, you use the private key, apply the algorithm, and you get the plaintext back. You cannot get the plaintext back with the public key.
  • GnuPG doesn’t actually do this, at least not directly. To encrypt, GnuPG generates a new session key every time you encrypt something. You don’t interact with that session key directly. The session key is a symmetric key, which means that it is used both to encrypt, and to decrypt. To prevent an attacker from knowing the session key, it is encrypted as outlined before using the public key. So when you think you are encrypting something with your GPG keys, you really encrypt it with a new session key generated for the purpose, and then you encrypt the session key with the public key, and you send both encrypted pieces together. The receiver decrypts the session key, and they uses the session key to decrypt the message.
  • To sign a document, the private key can be used as the encryption key, and the public key as a decryption key.
  • GnuPG, however, does this only indirectly: instead of encrypting the document with the private key, it encrypts the hash of the document, where the hash is a relatively short number generated from the document. To verify the signature, the receiver re-generates the hash, and decrypts the signature with the public key, which should produce the same hash.

So far, so good. Now we get to subkeys. Turns out the GnuPG project has awful terminology, and so I’ll make up a new term to disambiguate, called the composite key.

  • If you create yourself a GnuPG key pair, you are actually creating two keys pairs, one called the “master signing key pair” and one called the “sub key pair”. They have the same length. Also, the public keys have some meta-data including user IDs of the key’s owner and when the key was created and will expire. I will call those “public keys plus metadata” “composite public key”.
  • To see this for user, execute:
    gpg --edit-key

    which shows the (master signing, and sub) public keys, and then execute


    which shows the (master signing, and sub) private keys.

  • When you give your public key to somebody else, you actually give them the “composite public key”: the public key of the master signing keypair, the public key of the subkey pair, and the associated meta-data.
  • These pieces are held together by a signature. By default, your newly generated composite public key is signed with the private key of your signing key. You can see that by executing:

    By looking closely, you can see which key was used to sign.

  • There can be more than one sub-keypair per signing key. Those sub-keypairs are used for encrypting and signing as a matter of course, and can be changed regularly. They can also use different strengths and algorithms. People you communicate with know it’s you because the master signing key — which is used for signatures of the composite keys — remains the same.
  • Due to some side effects of key distribution, it is generally better to revoke sub-keys than to delete them.
  • To revoke, the master signing key is used to sign the revoked sub-key (presumably with some meta-data that expresses “revoked”)

Now comes the web of trust:

  •  You can trust somebody ultimately (“your trust in yourself”), full (“their signature is as good as your own”), marginal (“maybe”), none (“don’t trust”) and unknown (“not determined yet”). The trust you associate with somebody is considered private information (no public social network!)
  • To see or edit trust, execute
  • When you assign a trust level to a key, you sign that key (presumably with some meta-data that expresses the level, and “trust”)
  • To determine whether or not to trust a key, various algorithms can be used. The default in GnuPG is: you trust keys that either 1) you signed yourself or 2) were signed by somebody you fully trust, or 3) were signed by at least three people who you trust marginally. This is applied iteratively over no more than five hops.

Aha! (Pointers to errors and omissions appreciated in the comments.)