One central (and non-trivial) element of OpenPGP are certificates (also often called "OpenPGP keys"). OpenPGP certificates are relatively complex data structures, so it's good to have a clear mental model of them.
Independent of the distinction between private and public keys, in OpenPGP, the term "key" is used to refer to three different layers, all related but distinct:
1. A (bare) "cryptographic key" (without additional metadata). Those might be the private and/or public parameters that form a key, e.g., in case of an RSA private key, the exponent `d` along with the prime numbers `p` and `q`.
2. An OpenPGP *component key*: Either an "OpenPGP primary key", or an "OpenPGP subkey". A component key is one building block of an OpenPGP certificate. It consist of a (bare) cryptographic keypair combined some invariant metadata (e.g. key creation time).
3. An "OpenPGP certificate" (or "OpenPGP key"): Consists of a number of component keys plus additional elements, such as identity information. (e.g. OpenPGP "key servers" serve this type of object).
All elements of an OpenPGP certificate are structured around one central element: the *OpenPGP primary key*. The primary key acts as a personal CA for the key's owner: It can make cryptographic statements about subkeys, identities, expiration times, revocation, ...
Note that OpenPGP certificates are typically long-lived and may be changed (typically by their owner), over time. Components can be added and invalidated, over the lifetime of a certificate
For each OpenPGP component key, an *OpenPGP fingerprint* can be derived from the combination of the public key material and creation timestamp (plus additional algorithm parameters, for [ECDH Keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ecd)):
[^keyid]: Sometimes, a shortened (64 bit) version of the fingerprint is used instead of the full fingerprint, like this: `C8B8 6AC4 2455 4239` (the rightmost 64 bit of the fingerprint). This type of identifier is called a "Key ID". Historically, 32 bit shorthand identifiers have been used with PGP, like this: `2455 4239`. You may still see such identifiers in very old documents about PGP, but 32 bit identifiers have [been unfit for purpose for a long time](https://evil32.com/). At some point, 32 bit identifiers were called "short Key ID", while 64 bit identifiers were called "long Key ID".
Subkeys have the same structure as the primary key, but play a subtly different role in the certificate. Subkeys are cryptographically linked with the primary key (more on this below).
Each component key has ["Key Flags"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3.21) that specify which types of operation the key can perform.
It is considered good practice to have separate component keys for each type of operation (specifically: to allow only *Certification* operations for the primary key, and to have separate *Signing*, *Encryption* and *Authentication* subkeys).
(Aside: with ECC algorithms, it's actually not possible to share encryption functionality with the signing-based functionalities, e.g.: ed25519 used for signing; cv25519 used for encryption.)
### Linking the components of an OpenPGP certificate together ("bindings")
Internally, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just stringed together, one after the other. When a certificate is stored in a file[^tpk], it's easy to remove some of these packets, or add new ones.
[^tpk]: When an OpenPGP certificate is stored as a file, it's in a format that is called [transferable public key](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-transferable-public-keys) in the RFC
However, as the owner of my certificate, I don't want a third party to add subkeys (or add identity claims) to my certificate, pretending that I put those components there.
To prevent such malicious addition of components, OpenPGP uses cryptographic signatures. These signatures show the cryptographic identity that has linked a component to an OpenPGP certificate (in many cases, the linking is done by the primary key of the certificate in question).
So while anyone can still unilaterally put subkeys and identity claims into a file with my OpenPGP certificate, OpenPGP implementations that read the file are expected to discard components that aren't cryptographically linked to my certificate.
Linking a subkey to an OpenPGP certificate is done with a ["Subkey Binding Signature"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.1). Such a signature signals that the "primary key wants to be associated with the subkey".
When binding a signing subkey to a primary key, it is not sufficient that the "primary key wants to be associated with the subkey." In addition, the subkey must signal that it wants to be associated with that primary key.
This additional "Primary Key Binding Signature" is informally called a "back signature" (because the subkey uses the signature to point "back" to the primary key).
OpenPGP certificates often contain identity markers. Typically, in the form of "User ID"s (however, User Attributes are analogous for the purpose of this section).
For example, above, we saw the User ID "Alice Adams <alice@example.org>" associated with Alice's key `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239`.
Alice can link a User ID to her OpenPGP certificate with a cryptographic signature. To link a User ID, a signature of the type `PositiveCertification` is created. The signature is issued using the primary (secret) key.
Some OpenPGP subsystems may add User IDs to a certificate, which are not bound to the primary key by the certificate's owner. This can be useful to store local identity information (e.g. sequoia's public store).
There is an ongoing effort to establish new terminology around "keys." In particular, to use the term "certificate" instead of "(OpenPGP) public key."
Note: there is also the related, but distinct, concept of [cryptographic "keys"](https://en.wikipedia.org/wiki/Key_(cryptography)). OpenPGP certificates/keys contain one or more cryptographic key(s), among many other components.
An OpenPGP certificate/key consists of a number of elements, many of them optional. OpenPGP certificates/keys always make use of [Public-key cryptography (asymmetric cryptography)](https://en.wikipedia.org/wiki/Public-key_cryptography).
As a consequence, some elements of OpenPGP certificates/keys represent "private" (sometimes referred to as "secret") key material, while other elements represent "public" key material. Yet other elements contain metadata, and finally there are elements that serve as glue ("binding") between the various other elements of a certificate.
To hand out copies of one's OpenPGP key to third parties, implementations can generate a "certificate" / "public key" representation ([Transferable Public Keys](https://tools.ietf.org/html/rfc4880#section-11.1) in the RFC), which consists of all the elements of the certificate, except for the private key material (and the optional [S2K configuration](https://tools.ietf.org/html/rfc4880#section-3.7.2.1)).
The counterpart is called [Transferable Secret Keys](https://tools.ietf.org/html/rfc4880#section-11.2) in the RFC. That is, an OpenPGP key that includes private key material.
Looking into the internals of this key with `sq packet dump --hex`, or https://dump.sequoia-pgp.org/, we see that it is made up of a sequence of "Packets":
* First, a [*"Secret-Key Packet"*](https://tools.ietf.org/html/rfc4880#section-5.5.1.3), which contains the actual cryptographic key data. Note: the "Secret-Key" Packet contains both the private and the public part of the key. We also see in the output that this packet is "Unencrypted" (i.e. not password-protected).
* Second, a [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) of type 0x1F, *"Signature directly on a key"*. This packet *"binds the information in the Signature subpackets to the key"*. Each entry under "Signature Packet -> Hashed area" is one Signature subpacket, including for example information about algorithm preferences (*"Symmetric algo preferences"* and *"Hash preferences"*).
Let's compare this with the same certificate seen as an armored "public" certificate (that is, a variant of the key above, but without the private key material. An OpenPGP user might give such a certificate to a communication partner, so that the remote party could send encrypted messages to the user):
The public certificate uses the packet type "Public-Key Packet" instead of "Secret-Key Packet". The two packet types are very similar. The "Public-Key Packet" leaves out two types of data
In the following examples, we will look at OpenPGP private keys only. The corresponding public certificates are easy to imagine (just leave out the private key material).
To look into these, we'll make a certificate that has one [User ID](https://tools.ietf.org/html/rfc4880#section-5.11). User IDs are *"intended to represent the name and email address of the key holder"*. A certificate can have multiple User IDs associated with it.
* Third, a [*"User ID Packet"*](https://tools.ietf.org/html/rfc4880#section-5.11), which contains the name and email address we used
* Finally, a [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) of type 0x13, *"Positive certification of a User ID and Public-Key packet"*. This is a cryptographic artifact that "binds the User ID packet and the Key packet together", i.e. it certifies that the owner of the key wants this User ID associated with their key. (Only the person who controls the private part of this key can create this signature packet. The signature serves as proof that the owner of the key has added this User ID to the certificate)
From here on, we'll look at the dumps in shorter format (you can see more detail by copying the certificates into the web-dumper at https://dump.sequoia-pgp.org/ and checking the "HexDump" checkbox).