openpgp-notes/book/source/04-certificates.md
2023-10-03 19:14:39 +02:00

727 lines
38 KiB
Markdown

(certificates_chapter)=
# Certificates
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.
## Terminology: The various meanings of "key"
### Private vs. public keys
First, without additional context, the word "key" can refer either to public, or to private key material.
### Layers of "keys," in OpenPGP
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 consists 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).
In the following section, we'll look at the two OpenPGP-specific layers (2 and 3).
## Structure of OpenPGP certificates
An OpenPGP certificate (or "OpenPGP key") is a collection of an arbitrary number of elements. These elements are:
- component keys,
- identity information, and
- other metadata.
We sometimes collectively refer to component keys and identity information as the "components" of a certificate.
```{figure} diag/OpenPGP\ Certificate.svg
Typical components in an OpenPGP certificate
```
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 certificate's owner: It can make cryptographic statements about subkeys, identities, expiration, revocation, ...
```{note}
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
```
### OpenPGP component keys
An OpenPGP component key (either the "OpenPGP primary key," or an "OpenPGP subkey") consists mainly of an asymmetric cryptographic keypair:
```{figure} diag/keypair.png
---
---
A cryptographic keypair
```
Recall that in many contexts, only the public key material is present:
```{figure} diag/keypair_pub.png
---
---
Only the public part of a cryptographic keypair
```
Besides a cryptographic keypair, an OpenPGP component key contains additional metadata (including a creation timestamp):
```{figure} diag/primary_key.png
---
---
An OpenPGP component key
```
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)):
```{figure} diag/fingerprint.png
---
---
Each OpenPGP component key has a fingerprint
```
The fingerprint of our example component OpenPGP key is `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3` [^keyid].
[^keyid]: In OpenPGP version 4, the rightmost 64 bit were sometimes used as a shorter identifier, called "Key ID".
E.g., an OpenPGP version 4 certificate with the fingerprint `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239` might be referred to by the 64 bit Key ID `C8B8 6AC4 2455 4239` or styled as `0xC8B86AC424554239`.
Historically, even shorter 32 bit identifiers have sometimes been used, like this: `2455 4239`, or `0x24554239`. You may still see such identifiers in very old documents about PGP. However, 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".
#### Primary key
The "OpenPGP primary key" has the same structure as all other component keys. But it serves a central role:
- Its fingerprint is used as the unique identifier for the full OpenPGP certificate.
- In addition, it is used for lifecycle operations, such as adding or invalidating subkeys or identities in a certificate.
```{admonition} Terminology
:class: note
In the RFC, the OpenPGP primary key is also sometimes referred to as "top-level key." Historically, it has sometimes informally been called "master key."
```
#### Subkeys
In addition to the primary key, modern OpenPGP certificates usually contain "subkeys" in addition to the primary key.
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).
```{figure} diag/with_subkeys.png
:name: Certificate with Subkeys
:alt: Three component keys. The primary key is shown at the top. It can be used for certification. Below it, linked with arrows, are two more component keys, used as subkeys. They are marked as "for encryption" and "for signing", respectively.
:width: 80%
:align: center
OpenPGP certificates can contain any number of subkeys
```
As before, a component key consists of a cryptographic keypair combined with additional metadata.
Each component key (this includes the primary key, and all subkeys) has a marker that specifies which operations the component key can perform.
#### Key Flags: defining what operations a component key can perform
Each component key has ["Key Flags"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-flags) that specify which types of operation the key can perform.
The commonly used flags are:
- **C**ertification
- **S**igning
- **E**ncryption
- **A**uthentication
Only the primary key can perform "certification" operations. All other operations can be performed by either the primary key or subkeys.
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.)
### Identity components
#### User IDs
An OpenPGP certificate can contain any number of User IDs. Each user ID associates the certificate with an identity.
Typically, these identities are composed of a name and an email address.
```{figure} diag/user_id.png
---
---
OpenPGP certificates can contain any number of User IDs
```
#### Primary UserID and its implications
#### User attributes
User attributes are similar to User IDs, but less commonly used.
### Linking the components of an OpenPGP certificate together ("bindings")
So far we've looked at the components in an OpenPGP certificate, but certificates actually contain another set of elements, which bind the components together, and add metadata to them.
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.
#### "Binding" subkeys to an OpenPGP certificate
Linking a subkey to an OpenPGP certificate is done with a ["Subkey Binding Signature"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding). Such a signature signals that the "primary key wants to be associated with the subkey".
The subkey binding signature also adds metadata.
```{figure} diag/subkey_binding.png
---
---
Linking an OpenPGP subkey to the primary key with a binding signature
```
##### Signature Subpackets
- (key-) expiration
- flags
##### Binding signing subkeys
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.
Otherwise, Alice could "adopt" Bob's signing subkey and convincingly claim that she made signatures that were in fact issued by Bob.
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).
#### Self-certification of identity claims
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 `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3`.
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.
```{figure} diag/user_id_certification.png
---
---
Linking a User ID to an OpenPGP certificate
```
## Third party (identity) certifications
## Revocations
Note: certification signatures [can be made irrevocable](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-revocable).
### Hard vs. soft revocations
## Advanced topics
### Certificate Management / Evolution of a certificate over time
Minimized versions, merging, effective "append only" semantics, ...
### Merging
- How to merge two copies of the same certificate?
- Canonicalization
### How to generate "minimized" certificate?
### When are certificates valid?
- Full certificate: Primary revoked/key expired/binding signature expired,
- Subkey: Revoked/key expired/binding signature expired
- User ID: revoked, binding expired, ...
### Best Practices regarding Key Freshness
- Expiry
- Subkey rotation
### Metadata Leak of Social Graph
### Adding unbound User IDs to a certificate
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).
## Zooming in: Package structure
To use OpenPGP, we need "(OpenPGP) keys."
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://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#transferable-public-keys) in the RFC), which consists of all the elements of the certificate, except for the private key material (and the optional [S2K configuration](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-string-to-key-s2k-specifier)).
The counterpart is called [Transferable Secret Keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#transferable-secret-keys) in the RFC. That is, an OpenPGP certificate that includes private key material.
### A minimal OpenPGP key
A minimal OpenPGP key consists of the Secret-Key Packet for the primary key, and a self-certification (the Direct Key Signature).
#### Seen as a private OpenPGP key
A minimal version of [Alice's private key](alice_priv) (in ASCII-armored representation) looks like this:
```text
-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3
xUsGZRbqphsAAAAgUyTpQ6+rFfdu1bUSmHlpzRtdEGXr50Liq0f0hrOuZT4A7+GZ
tV8R+6qT6CadO7ItciB9/71C3UvpozaBO6XMz/vCtgYfGwoAAAA9BYJlFuqmBYkF
pI+9AwsJBwMVCggCmwECHgEiIQaqoYy7JUaFxYNYMgVj/Te2fzMA+fsOxFc3jNKf
ECaYswAAAAoJEKqhjLslRoXFZ0cgouNjgeNr0E9W18g4gAIl6FM5SWuQxg12j0S0
7ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L+BXIoY2sIEQrLd4TAEEy
0BA8aQZTPEmMdiOCM1QB+V+BQZAO
=f0GN
-----END PGP PRIVATE KEY BLOCK-----
```
If we decode this OpenPGP data, we see that the key is made up of a sequence of two packets:
```text
$ sq packet dump --hex alice_minimal.priv
Secret-Key Packet, new CTB, 2 header bytes + 75 bytes
Version: 6
Creation time: 2023-09-29 15:17:58 UTC
Pk algo: Ed25519
Pk size: 256 bits
Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
KeyID: AAA18CBB254685C5
Secret Key:
Unencrypted
00000000 c5 CTB
00000001 4b length
00000002 06 version
00000003 65 16 ea a6 creation_time
00000007 1b pk_algo
00000008 00 00 00 20 public_len
0000000c 53 24 e9 43 ed25519_public
00000010 af ab 15 f7 6e d5 b5 12 98 79 69 cd 1b 5d 10 65
00000020 eb e7 42 e2 ab 47 f4 86 b3 ae 65 3e
0000002c 00 s2k_usage
0000002d ef e1 99 ed25519_secret
00000030 b5 5f 11 fb aa 93 e8 26 9d 3b b2 2d 72 20 7d ff
00000040 bd 42 dd 4b e9 a3 36 81 3b a5 cc cf fb
Signature Packet, new CTB, 2 header bytes + 182 bytes
Version: 6
Type: DirectKey
Pk algo: Ed25519
Hash algo: SHA512
Hashed area:
Signature creation time: 2023-09-29 15:17:58 UTC (critical)
Key expiration time: P1095DT62781S (critical)
Symmetric algo preferences: AES256, AES128
Hash preferences: SHA512, SHA256
Key flags: C (critical)
Features: MDC
Issuer Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
Unhashed area:
Issuer: AAA18CBB254685C5
Digest prefix: 6747
Level: 0 (signature over data)
00000000 c2 CTB
00000001 b6 length
00000002 06 version
00000003 1f type
00000004 1b pk_algo
00000005 0a hash_algo
00000006 00 00 00 3d hashed_area_len
0000000a 05 subpacket length
0000000b 82 subpacket tag
0000000c 65 16 ea a6 sig creation time
00000010 05 subpacket length
00000011 89 subpacket tag
00000012 05 a4 8f bd key expiry time
00000016 03 subpacket length
00000017 0b subpacket tag
00000018 09 07 pref sym algos
0000001a 03 subpacket length
0000001b 15 subpacket tag
0000001c 0a 08 pref hash algos
0000001e 02 subpacket length
0000001f 9b subpacket tag
00000020 01 key flags
00000021 02 subpacket length
00000022 1e subpacket tag
00000023 01 features
00000024 22 subpacket length
00000025 21 subpacket tag
00000026 06 version
00000027 aa a1 8c bb 25 46 85 c5 83 issuer fp
00000030 58 32 05 63 fd 37 b6 7f 33 00 f9 fb 0e c4 57 37
00000040 8c d2 9f 10 26 98 b3
00000047 00 00 00 0a unhashed_area_len
0000004b 09 subpacket length
0000004c 10 subpacket tag
0000004d aa a1 8c issuer
00000050 bb 25 46 85 c5
00000055 67 digest_prefix1
00000056 47 digest_prefix2
00000057 20 salt_len
00000058 a2 e3 63 81 e3 6b d0 4f salt
00000060 56 d7 c8 38 80 02 25 e8 53 39 49 6b 90 c6 0d 76
00000070 8f 44 b4 ec 4c 42 38 8e
00000078 4d 3d 10 c2 ad 29 c0 57 ed25519_sig
00000080 ce 66 01 73 b3 78 81 9e 89 52 cf 43 8d 28 11 a9
00000090 77 09 7f cb f8 15 c8 a1 8d ac 20 44 2b 2d de 13
000000a0 00 41 32 d0 10 3c 69 06 53 3c 49 8c 76 23 82 33
000000b0 54 01 f9 5f 81 41 90 0e
```
* First, a [*"Secret-Key Packet"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#seckey), 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 [*"Direct Key Signature"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key) (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"*).
```{figure} diag/key-minimal.png
---
---
A minimal OpenPGP key, visualized
```
#### Seen as a public certificate
Let's compare this with the same certificate seen as an armored OpenPGP certificate (that is, a "public key" 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):
```text
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3
xioGZRbqphsAAAAgUyTpQ6+rFfdu1bUSmHlpzRtdEGXr50Liq0f0hrOuZT7CtgYf
GwoAAAA9BYJlFuqmBYkFpI+9AwsJBwMVCggCmwECHgEiIQaqoYy7JUaFxYNYMgVj
/Te2fzMA+fsOxFc3jNKfECaYswAAAAoJEKqhjLslRoXFZ0cgouNjgeNr0E9W18g4
gAIl6FM5SWuQxg12j0S07ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L
+BXIoY2sIEQrLd4TAEEy0BA8aQZTPEmMdiOCM1QB+V+BQZAO
=5nyq
-----END PGP PUBLIC KEY BLOCK-----
```
```text
$ sq packet dump --hex alice_minimal.pub
Public-Key Packet, new CTB, 2 header bytes + 42 bytes
Version: 6
Creation time: 2023-09-29 15:17:58 UTC
Pk algo: Ed25519
Pk size: 256 bits
Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
KeyID: AAA18CBB254685C5
00000000 c6 CTB
00000001 2a length
00000002 06 version
00000003 65 16 ea a6 creation_time
00000007 1b pk_algo
00000008 00 00 00 20 public_len
0000000c 53 24 e9 43 ed25519_public
00000010 af ab 15 f7 6e d5 b5 12 98 79 69 cd 1b 5d 10 65
00000020 eb e7 42 e2 ab 47 f4 86 b3 ae 65 3e
Signature Packet, new CTB, 2 header bytes + 182 bytes
Version: 6
Type: DirectKey
Pk algo: Ed25519
Hash algo: SHA512
Hashed area:
Signature creation time: 2023-09-29 15:17:58 UTC (critical)
Key expiration time: P1095DT62781S (critical)
Symmetric algo preferences: AES256, AES128
Hash preferences: SHA512, SHA256
Key flags: C (critical)
Features: MDC
Issuer Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
Unhashed area:
Issuer: AAA18CBB254685C5
Digest prefix: 6747
Level: 0 (signature over data)
00000000 c2 CTB
00000001 b6 length
00000002 06 version
00000003 1f type
00000004 1b pk_algo
00000005 0a hash_algo
00000006 00 00 00 3d hashed_area_len
0000000a 05 subpacket length
0000000b 82 subpacket tag
0000000c 65 16 ea a6 sig creation time
00000010 05 subpacket length
00000011 89 subpacket tag
00000012 05 a4 8f bd key expiry time
00000016 03 subpacket length
00000017 0b subpacket tag
00000018 09 07 pref sym algos
0000001a 03 subpacket length
0000001b 15 subpacket tag
0000001c 0a 08 pref hash algos
0000001e 02 subpacket length
0000001f 9b subpacket tag
00000020 01 key flags
00000021 02 subpacket length
00000022 1e subpacket tag
00000023 01 features
00000024 22 subpacket length
00000025 21 subpacket tag
00000026 06 version
00000027 aa a1 8c bb 25 46 85 c5 83 issuer fp
00000030 58 32 05 63 fd 37 b6 7f 33 00 f9 fb 0e c4 57 37
00000040 8c d2 9f 10 26 98 b3
00000047 00 00 00 0a unhashed_area_len
0000004b 09 subpacket length
0000004c 10 subpacket tag
0000004d aa a1 8c issuer
00000050 bb 25 46 85 c5
00000055 67 digest_prefix1
00000056 47 digest_prefix2
00000057 20 salt_len
00000058 a2 e3 63 81 e3 6b d0 4f salt
00000060 56 d7 c8 38 80 02 25 e8 53 39 49 6b 90 c6 0d 76
00000070 8f 44 b4 ec 4c 42 38 8e
00000078 4d 3d 10 c2 ad 29 c0 57 ed25519_sig
00000080 ce 66 01 73 b3 78 81 9e 89 52 cf 43 8d 28 11 a9
00000090 77 09 7f cb f8 15 c8 a1 8d ac 20 44 2b 2d de 13
000000a0 00 41 32 d0 10 3c 69 06 53 3c 49 8c 76 23 82 33
000000b0 54 01 f9 5f 81 41 90 0e
```
Note that the two OpenPGP artifacts (OpenPGP certificate and OpenPGP private key) are almost identical.
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
* the private key material (visualized in red), and
* s2k configuration data, if any (this example doesn't have any).
s2k is used when the secret key material is password-protected.
```{figure} diag/pubcert-minimal.png
---
---
A minimal OpenPGP public certificate, visualized
```
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).
### User IDs
User IDs are a mechanism for attaching *identities* to an OpenPGP certificate. Typically, a User ID will contain a name and an email address.
To look into these, we'll make a certificate that has one [User ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#uid). 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.
Let's look into the details of this key:
```text
-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3
Comment: <alice@example.org>
xUsGZRbqphsAAAAgUyTpQ6+rFfdu1bUSmHlpzRtdEGXr50Liq0f0hrOuZT4A7+GZ
tV8R+6qT6CadO7ItciB9/71C3UvpozaBO6XMz/vCtgYfGwoAAAA9BYJlFuqmBYkF
pI+9AwsJBwMVCggCmwECHgEiIQaqoYy7JUaFxYNYMgVj/Te2fzMA+fsOxFc3jNKf
ECaYswAAAAoJEKqhjLslRoXFZ0cgouNjgeNr0E9W18g4gAIl6FM5SWuQxg12j0S0
7ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L+BXIoY2sIEQrLd4TAEEy
0BA8aQZTPEmMdiOCM1QB+V+BQZAOzRM8YWxpY2VAZXhhbXBsZS5vcmc+wrkGExsK
AAAAQAWCZRbqpgWJBaSPvQMLCQcDFQoIApkBApsBAh4BIiEGqqGMuyVGhcWDWDIF
Y/03tn8zAPn7DsRXN4zSnxAmmLMAAAAKCRCqoYy7JUaFxdu4IIotb9pnNbxdBHe0
nWeobsXWiFNf4u/5Zgi/wuDbwFYN69QspRkBD7om0IKiz1zreqly2fOyZgeLsro9
t4nkdgRuNSQrJymDvpGceGrMtNVpR3YsKdZUv0MZBP9TmMDVCw==
=bgQM
-----END PGP PRIVATE KEY BLOCK-----
```
```text
$ sq packet dump --hex alice_userid.priv
Secret-Key Packet, new CTB, 2 header bytes + 75 bytes
Version: 6
Creation time: 2023-09-29 15:17:58 UTC
Pk algo: Ed25519
Pk size: 256 bits
Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
KeyID: AAA18CBB254685C5
Secret Key:
Unencrypted
00000000 c5 CTB
00000001 4b length
00000002 06 version
00000003 65 16 ea a6 creation_time
00000007 1b pk_algo
00000008 00 00 00 20 public_len
0000000c 53 24 e9 43 ed25519_public
00000010 af ab 15 f7 6e d5 b5 12 98 79 69 cd 1b 5d 10 65
00000020 eb e7 42 e2 ab 47 f4 86 b3 ae 65 3e
0000002c 00 s2k_usage
0000002d ef e1 99 ed25519_secret
00000030 b5 5f 11 fb aa 93 e8 26 9d 3b b2 2d 72 20 7d ff
00000040 bd 42 dd 4b e9 a3 36 81 3b a5 cc cf fb
Signature Packet, new CTB, 2 header bytes + 182 bytes
Version: 6
Type: DirectKey
Pk algo: Ed25519
Hash algo: SHA512
Hashed area:
Signature creation time: 2023-09-29 15:17:58 UTC (critical)
Key expiration time: P1095DT62781S (critical)
Symmetric algo preferences: AES256, AES128
Hash preferences: SHA512, SHA256
Key flags: C (critical)
Features: MDC
Issuer Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
Unhashed area:
Issuer: AAA18CBB254685C5
Digest prefix: 6747
Level: 0 (signature over data)
00000000 c2 CTB
00000001 b6 length
00000002 06 version
00000003 1f type
00000004 1b pk_algo
00000005 0a hash_algo
00000006 00 00 00 3d hashed_area_len
0000000a 05 subpacket length
0000000b 82 subpacket tag
0000000c 65 16 ea a6 sig creation time
00000010 05 subpacket length
00000011 89 subpacket tag
00000012 05 a4 8f bd key expiry time
00000016 03 subpacket length
00000017 0b subpacket tag
00000018 09 07 pref sym algos
0000001a 03 subpacket length
0000001b 15 subpacket tag
0000001c 0a 08 pref hash algos
0000001e 02 subpacket length
0000001f 9b subpacket tag
00000020 01 key flags
00000021 02 subpacket length
00000022 1e subpacket tag
00000023 01 features
00000024 22 subpacket length
00000025 21 subpacket tag
00000026 06 version
00000027 aa a1 8c bb 25 46 85 c5 83 issuer fp
00000030 58 32 05 63 fd 37 b6 7f 33 00 f9 fb 0e c4 57 37
00000040 8c d2 9f 10 26 98 b3
00000047 00 00 00 0a unhashed_area_len
0000004b 09 subpacket length
0000004c 10 subpacket tag
0000004d aa a1 8c issuer
00000050 bb 25 46 85 c5
00000055 67 digest_prefix1
00000056 47 digest_prefix2
00000057 20 salt_len
00000058 a2 e3 63 81 e3 6b d0 4f salt
00000060 56 d7 c8 38 80 02 25 e8 53 39 49 6b 90 c6 0d 76
00000070 8f 44 b4 ec 4c 42 38 8e
00000078 4d 3d 10 c2 ad 29 c0 57 ed25519_sig
00000080 ce 66 01 73 b3 78 81 9e 89 52 cf 43 8d 28 11 a9
00000090 77 09 7f cb f8 15 c8 a1 8d ac 20 44 2b 2d de 13
000000a0 00 41 32 d0 10 3c 69 06 53 3c 49 8c 76 23 82 33
000000b0 54 01 f9 5f 81 41 90 0e
User ID Packet, new CTB, 2 header bytes + 19 bytes
Value: <alice@example.org>
00000000 cd CTB
00000001 13 length
00000002 3c 61 6c 69 63 65 40 65 78 61 6d 70 6c 65 value
00000010 2e 6f 72 67 3e
Signature Packet, new CTB, 2 header bytes + 185 bytes
Version: 6
Type: PositiveCertification
Pk algo: Ed25519
Hash algo: SHA512
Hashed area:
Signature creation time: 2023-09-29 15:17:58 UTC (critical)
Key expiration time: P1095DT62781S (critical)
Symmetric algo preferences: AES256, AES128
Hash preferences: SHA512, SHA256
Primary User ID: true (critical)
Key flags: C (critical)
Features: MDC
Issuer Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3
Unhashed area:
Issuer: AAA18CBB254685C5
Digest prefix: DBB8
Level: 0 (signature over data)
00000000 c2 CTB
00000001 b9 length
00000002 06 version
00000003 13 type
00000004 1b pk_algo
00000005 0a hash_algo
00000006 00 00 00 40 hashed_area_len
0000000a 05 subpacket length
0000000b 82 subpacket tag
0000000c 65 16 ea a6 sig creation time
00000010 05 subpacket length
00000011 89 subpacket tag
00000012 05 a4 8f bd key expiry time
00000016 03 subpacket length
00000017 0b subpacket tag
00000018 09 07 pref sym algos
0000001a 03 subpacket length
0000001b 15 subpacket tag
0000001c 0a 08 pref hash algos
0000001e 02 subpacket length
0000001f 99 subpacket tag
00000020 01 primary user id
00000021 02 subpacket length
00000022 9b subpacket tag
00000023 01 key flags
00000024 02 subpacket length
00000025 1e subpacket tag
00000026 01 features
00000027 22 subpacket length
00000028 21 subpacket tag
00000029 06 version
0000002a aa a1 8c bb 25 46 issuer fp
00000030 85 c5 83 58 32 05 63 fd 37 b6 7f 33 00 f9 fb 0e
00000040 c4 57 37 8c d2 9f 10 26 98 b3
0000004a 00 00 00 0a unhashed_area_len
0000004e 09 subpacket length
0000004f 10 subpacket tag
00000050 aa a1 8c bb 25 46 85 c5 issuer
00000058 db digest_prefix1
00000059 b8 digest_prefix2
0000005a 20 salt_len
0000005b 8a 2d 6f da 67 salt
00000060 35 bc 5d 04 77 b4 9d 67 a8 6e c5 d6 88 53 5f e2
00000070 ef f9 66 08 bf c2 e0 db c0 56 0d
0000007b eb d4 2c a5 19 ed25519_sig
00000080 01 0f ba 26 d0 82 a2 cf 5c eb 7a a9 72 d9 f3 b2
00000090 66 07 8b b2 ba 3d b7 89 e4 76 04 6e 35 24 2b 27
000000a0 29 83 be 91 9c 78 6a cc b4 d5 69 47 76 2c 29 d6
000000b0 54 bf 43 19 04 ff 53 98 c0 d5 0b
```
Instead of two packets, as before, we see four packets in this certificate:
* First, a "Secret-Key Packet,"
* then a "Signature Packet" (these two packets are the same as above).
* Third, a [*"User ID Packet"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#uid), which contains the name and email address we used
* Finally, a [*"Positive Certification Signature"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (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)
### Subkeys
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).
### Certifications (Third Party Signatures)
### Revocations