mirror of
https://codeberg.org/openpgp/notes.git
synced 2024-11-23 16:12:05 +01:00
ch4: improvements to "zooming in"
This commit is contained in:
parent
ec78df2453
commit
c657d64734
1 changed files with 40 additions and 89 deletions
|
@ -287,6 +287,8 @@ Now that we've established the concepts of the components that OpenPGP certifica
|
|||
|
||||
We'll start with a very minimal version of [](alice_priv), stored as a "Transferrable Secret Key" (that is, including private key material).
|
||||
|
||||
In this section, we use the Sequoia-PGP tool `sq` to handle and transform our example OpenPGP key, and to inspect internal OpenPGP packet data.
|
||||
|
||||
One way to produce this minimal version of Alice's key is:
|
||||
|
||||
```text
|
||||
|
@ -379,7 +381,7 @@ KeyID: AAA18CBB254685C5
|
|||
|
||||
The Secret-Key Packet consists in large part of the actual cryptographic key data. Let's look at the packet field by field:
|
||||
|
||||
- `CTB: 0xc5`[^CTB]: The [Packet Tag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers) for this packet. The binary representation of this value is `11000101`. Bits 7 and 6 show that the packet is in "OpenPGP packet format" (as opposed to in "Legacy packet format"). The remaining 6 bits encode the Tag's value: "5". This is the value for a Secret-Key Packet, as shown in the list of [Packet Tags](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-tags).
|
||||
- `CTB: 0xc5`[^CTB]: The [Packet Tag](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers) for this packet. The binary representation of the value `0xc5` is `11000101`. Bits 7 and 6 show that the packet is in "OpenPGP packet format" (as opposed to in "Legacy packet format"). The remaining 6 bits encode the Tag's value: "5". This is the value for a Secret-Key Packet, as shown in the list of [Packet Tags](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-tags).
|
||||
- `length: 0x4b`: The remaining length of this packet.
|
||||
|
||||
The packet tag defines the semantics of the remaining data in the packet. We're looking at a Secret-Key Packet, which is a kind of [Key Material Packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-material-packets).
|
||||
|
@ -390,12 +392,12 @@ This means that the next part of the packet follows the structure of [Version 6
|
|||
|
||||
- `creation_time: 0x6516eaa6`: "The time that the key was created" (also see [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields))
|
||||
- `pk_algo: 0x1b`: "The public-key algorithm of this key" (decimal value 27, see the list of [Public-Key Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-algorithms))
|
||||
- `public_len: 0x00000020`: "Octet count for the following public key material"
|
||||
- `ed25519_public`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the public key material (the format is based on the value of `pk_algo`)
|
||||
- `public_len: 0x00000020`: "Octet count for the following public key material" (in this case, the length of the following `ed25519_public` field)
|
||||
- `ed25519_public`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the public key material (the format is based on the value of `pk_algo`), in this case 32 bytes of the Ed25519 public key
|
||||
|
||||
This concludes the Public Key section of the packet. The remaining data follows the [Secret-Key Packet Format](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-packet-formats):
|
||||
|
||||
- `s2k_usage: 0x00`: Specified that the secret-key data is not encrypted
|
||||
- `s2k_usage: 0x00`: [This "S2K usage" value](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-encryption-s2k-u) specifies that the secret-key data is not encrypted
|
||||
- `ed25519_secret`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the secret key data (the format is based on the value of `pk_algo`)
|
||||
|
||||
[^CTB]: Sequoia uses the term "CTB" (Cipher Type Byte) to refer to the RFC's ["Packet Tag"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers)
|
||||
|
@ -498,29 +500,31 @@ The next part of this packet contains "hashed subpacket data." A "subpacket data
|
|||
|
||||
There are two sets of "subpacket data" in a Signature: "hashed," and "unhashed." The difference is that the hashed subpackets are protected by the digital signature of this packet, while the unhashed subpackets are not.
|
||||
|
||||
The following subpacket data consists of sets of "subpacket length, subpacket tag, data." We'll show the information for each subpacket as one line, starting with the [subpacket type description](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-signature-subpacket-specifi) (based on the subpacket tag). Note that bit 7 of the subpacket tag signals if that subpacket is ["critical"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-5.2.3.7-10)
|
||||
The following subpacket data consists of sets of "subpacket length, subpacket tag, data." We'll show the information for each subpacket as one line, starting with the [subpacket type description](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-signature-subpacket-specifi) (based on the subpacket tag). Note that bit 7 of the subpacket tag signals if that subpacket is ["critical"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-5.2.3.7-10)[^critical].
|
||||
|
||||
- [Signature Creation Time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#signature-creation-subpacket) (type 2) *critical*: `0x6516eaa6`
|
||||
- [Key Expiration Time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-expiration-subpacket) (type 9) *critical*: `0x05a48fbd`
|
||||
- [Preferred Symmetric Ciphers for v1 SEIPD](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-v1-seipd) (type 11): `0x09 0x07`
|
||||
- [Preferred Hash Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-hashes-subpacket) (type 21): `0x0a 0x08`
|
||||
- [Key Flags](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-flags) (type 27) *critical*: `0x01`
|
||||
- [Features](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#features-subpacket) (type 30): `0x01`
|
||||
- [Issuer Fingerprint](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#issuer-fingerprint-subpacket) (type 33): `aaa18cbb254685c58358320563fd37b67f3300f9fb0ec457378cd29f102698b3`
|
||||
[^critical]: "Critical" here means: the receiver must be able to interpret the subpacket and is expected to fail, otherwise. non-critical subpackets may be ignored by the receiver
|
||||
|
||||
- [Signature Creation Time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#signature-creation-subpacket) (subpacket type 2) *critical*: `0x6516eaa6`
|
||||
- [Key Expiration Time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-expiration-subpacket) (subpacket type 9) *critical*: `0x05a48fbd`
|
||||
- [Preferred Symmetric Ciphers for v1 SEIPD](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-v1-seipd) (type 11): `0x09 0x07`. (These values [correspond to](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#symmetric-algos): "AES with 256-bit key" and "AES with 128-bit key")
|
||||
- [Preferred Hash Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-hashes-subpacket) (subpacket type 21): `0x0a 0x08`. (These values [correspond to](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-hash-algorithms): "SHA2-512" and "SHA2-256")
|
||||
- [Key Flags](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-flags) (subpacket type 27) *critical*: `0x01`. (This value [corresponds](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-flags) to the "certifications" key flag)
|
||||
- [Features](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#features-subpacket) (subpacket type 30): `0x01`. (This value [corresponds](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-features) to: "Symmetrically Encrypted Integrity Protected Data packet version 1")
|
||||
- [Issuer Fingerprint](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#issuer-fingerprint-subpacket) (subpacket type 33): `aaa18cbb254685c58358320563fd37b67f3300f9fb0ec457378cd29f102698b3` (this is the fingerprint of the component key that issued the signature in this packet. Not that here, the value is the primary key fingerprint of the certificate we're looking at.)
|
||||
|
||||
The next part of this packet contains "unhashed subpacket data":
|
||||
|
||||
- `unhashed_area_len: 0x0000000a`: Length of the following unhashed subpacket data
|
||||
- `unhashed_area_len: 0x0000000a`: Length of the following unhashed subpacket data.
|
||||
|
||||
As above, the following subpacket data consists of sets of "length, tag, data." In this case, only subpacket follows:
|
||||
|
||||
- [Issuer Key ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#issuer-keyid-subpacket) (type 16): `aaa18cbb254685c5`
|
||||
- [Issuer Key ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#issuer-keyid-subpacket) (subpacket type 16): `aaa18cbb254685c5` (this is the shortened version 6 "Key ID" of the fingerprint of this certificate's primary key)
|
||||
|
||||
This concludes the unhashed subpacket data.
|
||||
|
||||
- `digest_prefix: 0x6747`: "The left 16 bits of the signed hash value"
|
||||
- `salt_len, salt`: A random value with [matching size](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#hash-algorithms-registry) for the hash algorithm
|
||||
- `ed25519_sig`: [Algorithm-specific](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-fields-for-ed2) representation of the signature
|
||||
- `salt_len, salt`: A random [salt value](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-advantages-of-salted-signat) (the size must be [matching for the hash algorithm](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#hash-algorithms-registry))
|
||||
- `ed25519_sig`: [Algorithm-specific](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-fields-for-ed2) representation of the signature (in this case: 64 bytes of Ed25519 signature)
|
||||
|
||||
```{figure} diag/key-minimal.png
|
||||
:width: 40%
|
||||
|
@ -530,7 +534,7 @@ A minimal OpenPGP key, visualized
|
|||
|
||||
### Seen as an OpenPGP certificate
|
||||
|
||||
Let's now look at a "public key" view of the (very minimal) OpenPGP key above. That is, the same data, but without the private key material bits.
|
||||
Let's now look at a "public key" view of the (very minimal) OpenPGP key above. That is, the same data, but without the private key material parts.
|
||||
|
||||
An OpenPGP user might give such a certificate to a communication partner, or upload it to a key server:
|
||||
|
||||
|
@ -550,6 +554,11 @@ gAIl6FM5SWuQxg12j0S07ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L
|
|||
|
||||
```text
|
||||
$ sq packet dump --hex alice_minimal.pub
|
||||
```
|
||||
|
||||
The output now starts with a (primary) [Public-Key Packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-formats):
|
||||
|
||||
```text
|
||||
Public-Key Packet, new CTB, 2 header bytes + 42 bytes
|
||||
Version: 6
|
||||
Creation time: 2023-09-29 15:17:58 UTC
|
||||
|
@ -567,81 +576,15 @@ Public-Key Packet, new CTB, 2 header bytes + 42 bytes
|
|||
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.
|
||||
Note that the packet is almost identical to the Secret Key Packet seen above.
|
||||
|
||||
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 packet tag (called `CTB` in the output) has changed to the packet type ["Public-Key Packet"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-packet-tag-6) instead of "Secret-Key Packet."
|
||||
|
||||
* 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.
|
||||
The two packet types are very similar. Compared to the "Secret-Key Packet" packet shown above, this "Public-Key Packet" just leaves out the last section, which contained the private-key related fields `s2k_usage` and `ed25519_secret`.
|
||||
|
||||
The second packet in the certificate (the Direct Key Signature) is bit-for-bit identical as in the previous section. So we omit showing it again, here.
|
||||
|
||||
```{figure} diag/pubcert-minimal.png
|
||||
:width: 40%
|
||||
|
@ -649,10 +592,18 @@ The public certificate uses the packet type "Public-Key Packet" instead of "Secr
|
|||
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).
|
||||
In the following examples, we will only look at OpenPGP keys that include the private key material. The corresponding "certificate" variants, which only contain the public key material, are easy to imagine: like here, they just leave out the private key material.
|
||||
|
||||
### Subkeys
|
||||
|
||||
```{admonition} TODO
|
||||
:class: warning
|
||||
|
||||
The following text is unfinished and still needs processing/writing.
|
||||
|
||||
**This point marks the end of the material that should be read/edited.**
|
||||
```
|
||||
|
||||
From here on, we'll look at the dumps in shorter format (you can see more detail by copying the certificates into the ["Sequoia OpenPGP Packet dumper"](https://dump.sequoia-pgp.org/) and checking the "HexDump" checkbox).
|
||||
|
||||
### User IDs
|
||||
|
|
Loading…
Reference in a new issue