GnuPG Part 3 – Import, Sign, and Trust Keys

The purpose of public-key encryption software such as PGP is to enable secure communication with others. To that end, your GnuPG keyring is used to manage not just your own keys, but the public keys of those with whom you wish to communicate. To use GnuPG effectively, you must know how to import keys, how to sign them with your own key, and understand the Web of Trust.

Import a Key

Let’s say that Bobby and Alice want to be able to exchange messages and files securely. They would each export their public key to a file, as described in Part 2. Once they have received each other’s public keys, they can be imported using the --import option.

gpg --import

The imported key will then show up on the keyring.

gpg --list-keys
pub   rsa3072 2022-11-30 [SC] [expires: 2024-11-29]
uid           [ultimate] Bobby <>
sub   rsa3072 2022-11-30 [E] [expires: 2024-11-30]
sub   dsa2048 2022-12-01 [S] [expires: 2024-11-30]

pub   rsa3072 2022-12-01 [SC] [expires: 2024-11-30]
uid           [ unknown] Alice <>
sub   rsa3072 2022-12-01 [E] [expires: 2024-11-30]
sub   dsa2048 2022-12-01 [S] [expires: 2024-11-30]

Web of Trust

Importing keys is simple enough, but you may notice in the previous output that the trust level for Alice’s key is “unknown”. This is where key signing and the Web of Trust come in. (Careful not to confuse this with WOT, the browser extension by the same name. They are unrelated.)

In any public key system, the trustworthiness of a pubic key is proven by signing that key with an already trusted keypair. The private key of that keypair is used to sign, and anyone with the corresponding public key can verify the signature. In the more common X.509 standard, the signing of public keys is handled by centrally managed certificate authorities. PGP instead uses a distributed paradigm where individual users sign each other’s public keys. This is somewhat comparable to peer-to-peer file sharing vs client/server models. Other users who receive a public key can know that it is trustworthy if it is signed by other keys they already know and trust. This can get rather messy, so many PGP users will tell you that the best practice is to exchange and sign keys on a 1-on-1 basis.

Sign Keys

Assuming Bobby is confident that the public key he imported legitimately belongs to Alice, he can then sign that key with his own private key using the --sign-key option.

gpg --sign-key

You may notice that the --list-keys output now shows a “full” trust level of on the signed key. You can also use the --list-sig option to view all signatures on a key.

gpg --list-sig
pub   rsa3072 2022-12-01 [SC] [expires: 2024-11-30]
uid           [  full  ] Alice 
sig 3        2BC0AAE51BAFB0B3 2022-12-01  Alice 
sig          F30397D356C3E636 2022-12-05  Bobby 
sub   rsa3072 2022-12-01 [E] [expires: 2024-11-30]
sig          2BC0AAE51BAFB0B3 2022-12-01  Alice 
sub   dsa2048 2022-12-01 [S] [expires: 2024-11-30]
sig          2BC0AAE51BAFB0B3 2022-12-01  Alice 

Now Bobby’s system knows that Alice’s key is signed and trusted, but what about others? For this to be useful to Alice, Bobby must then export Alice’s signed key and send it back to her. She can then import it using the same --import command above, and Bobby’s signature will be added to her key on her own keyring; and will now be included when she exports it to send to others. All signed public keys should be sent directly back to their owners so that the signatures for each of those keys can be collected by the owner.

Set a Trust Level

The trust level effectively decides whether or not you trust a key. It is a local-only setting stored in the trustdb.gpg file and used to control your personal level of trust in the keys on your keyring. It does not have any affect on the broader validity of keys, which is determined by signatures. The trust level itself is less complicated than it may initially seem. Ultimately, keys (and therefore anything encrypted or signed by them) are either trusted or they are not. The trust level affects how this is determined.

Trust LevelDescription
UltimateThis trust level assigns complete trust regardless of the trust path, and is used only for your own keys. Any message signed using these keys is trusted. Any key that has been signed by these keys will also be trusted.
FullThis is used for keys that you fully trust to sign other keys. For instance, if Bobby assigns Full trust to Alice’s key, and she uses it to sign Malory’s key, Malory’s key will also be trusted. Full trust should only be used for keys that have been verified and signed. Signing a key will automatically assign it Full trust.
MarginalA key with this trust level is considered valid if it has been signed by at least three other keys with a Marginal trust-level. This option is not often used due to its complexity.
NeverThis is used to designate keys that you explicitly do not trust for whatever reason.
UnknownKeys with this level are not trusted. This is the default trust level assigned to unsigned, imported keys until they are signed or another trust level is configured.
UndefinedEffectively the same as Unknown, but is intentionally configured. This is typically used as a placeholder for keys that may have a trust level assigned at a later time.
RevokedThis indicates that a key has been revoked and is no longer trusted.

To manually configure a trust level, use the --edit-key option to enter interactive mode, and from there use the trust command. You will then be asked to enter a number from 1 to 5 to set the trust level.

gpg> trust
pub  rsa3072/2BC0AAE51BAFB0B3
     created: 2022-12-01  expires: 2024-11-30  usage: SC  
     trust: marginal      validity: full
sub  rsa3072/B7A021383ADD3D0F
     created: 2022-12-01  expires: 2024-11-30  usage: E   
sub  dsa2048/E1A00903B0E16687
     created: 2022-12-01  expires: 2024-11-30  usage: S   
[  full  ] (1). Alice 

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 1

Note that the trust level may not actually change depending on the signing status of the key. In practice it is typically not necessary to manually configure trust levels.

<< GnuPG Part 2 – Create and Manage Keys

>> GnuPG Part 4 – Encrypt and Sign Files