ch5: edits

This commit is contained in:
Heiko Schaefer 2023-11-24 20:12:14 +01:00
parent d9ebc63721
commit 9e233cc011
No known key found for this signature in database
GPG key ID: DAE9A9050FCCF1EB

View file

@ -12,9 +12,9 @@ Private key material is associated with component keys that are parts of [OpenPG
## Terminology: "Certificates" and "private keys"
In this document, we use the term *OpenPGP certificate* to refer to what are often called "OpenPGP public keys": OpenPGP certificates are the combination of component public keys, identity components, binding self-signatures and third-party certifications.
Recall that in this document, we use the term *OpenPGP certificate* to refer to what are often called "OpenPGP public keys": OpenPGP certificates are the combination of component public keys, identity components, binding self-signatures and third-party certifications (as discussed in the previous chapter, {ref}`certificates_chapter`).
This chapter is about the counterpart to the material in certificates: The corresponding *private key material* of component keys.
This chapter is about the remaining counterpart to the elements of certificates: The corresponding *private key material* of component keys.
In this book, we treat the private key material as logically separate from the OpenPGP certificate. A separate subsystem typically handles operations that use private key material. It is useful to think about OpenPGP certificates on one hand, and the associated private key material, on the other, as related but separate elements[^pkcs11]:
@ -22,15 +22,13 @@ In this book, we treat the private key material as logically separate from the O
:name: fig-openpgp-certificate-with-private-key-store
:alt: Depicts a diagram on white background with an OpenPGP Certificate and a private key store. Gray dotted lines connect the green public key symbols of the OpenPGP Certificate with red dotted private key symbols in the private key store.
An OpenPGP certificate, with the associated private key material handled by a key store subsystem.
An OpenPGP certificate, with the associated private key material handled in a separate subsystem.
```
[^pkcs11]: This kind of distinction between certificates (which combine public key material and identity information) on the one hand, and private key material on the other, is also applied in the data model of [PKCS #11](https://en.wikipedia.org/wiki/PKCS_11) cryptographic systems.
However, there is one exception. The cryptographic private key material is sometimes embedded in an OpenPGP framing format that also contains the certificate: Transferable secret keys (TSK).
Historically, terminology around OpenPGP certificates and keys has often been used inconsistently. The pair of terms "OpenPGP public key" and "OpenPGP private/secret keys" were commonly used (while the shorthand "OpenPGP key" can refer to both, depending on context).
## Transferable secret key format
Sometimes it is useful to handle OpenPGP certificates combined with private key material in the form of [*transferable secret keys (TSK)*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-transferable-secret-keys). Transferable secret keys are a serialized format that combines OpenPGP certificate data with the connected private key material, stored in a single file.
@ -52,7 +50,7 @@ The TSK format can be useful for backups of OpenPGP key material, or to move a k
Transferable secret keys are sometimes colloquially referred to as "OpenPGP private keys".
```
Historically, the concept of TSKs, which combine all aspects of an OpenPGP certificate and the associated private key material, has sometimes been conflated with OpenPGP private key operations.
Historically, the concept of TSKs, which combine all aspects of an OpenPGP certificate and the associated private key material, has sometimes been conflated with OpenPGP private key operations. We consider it more helpful to think of TSKs as a specialized format for storage/transport, and not as a data structure for use in a key store. Also see {ref}`key-store-design`.
(encrypted_secrets)=
## Protection of private key material in OpenPGP
@ -61,11 +59,11 @@ In OpenPGP format, private key material can optionally be protected with a [pass
Protecting private key material with a passphrase can be useful when a third party obtains a copy of the OpenPGP key data, but doesn't know the passphrase. In this scenario, the attacker may have obtained a copy of an OpenPGP key, but is unable to use it, because it is protected with a passphrase that is not known to the attacker.
### Passphrases to symmetric keys (S2K)
### Transforming a passphrase into a symmetric key
When protecting private key material in OpenPGP, a symmetric key is derived from the user's passphrase.
When protecting private key material in OpenPGP, a symmetric key is derived from the user's passphrase. This key is then used to protect the OpenPGP private key data.
For this purpose, OpenPGP defines a mechanism called [string-to-key (S2K)](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-string-to-key-s2k-specifier) that is used to derive (high-entropy) symmetric encryption keys from (lower-entropy) passphrases, using a [key derivation function (KDF)](https://en.wikipedia.org/wiki/Key_derivation_function).
For this purpose, the OpenPGP standard defines a family of mechanisms called [string-to-key (S2K)](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-string-to-key-s2k-specifier). These are used to derive (high-entropy) symmetric encryption keys from (lower-entropy) passphrases, using a [key derivation function (KDF)](https://en.wikipedia.org/wiki/Key_derivation_function).
```{figure} diag/passphrase_using_S2K.png
:name: fig-passphrase-using-s2k
@ -74,19 +72,25 @@ For this purpose, OpenPGP defines a mechanism called [string-to-key (S2K)](https
Deriving a symmetric key from a passphrase
```
This symmetric key is used to protect the private key material "at rest." That is, while it is stored on-disk. To use a passphrase-protected OpenPGP private key, it is decrypted using the symmetric key, and then used for a set of private key operations.
This symmetric key is used to protect the private key material "at rest." E.g., while it is stored on disk. To use a passphrase-protected OpenPGP private key, it is decrypted using the symmetric key, and used for private key operations, while it is temporarily unlocked, in memory.
#### S2K mechanisms for symmetric key generation
#### Mechanisms for symmetric key generation
Over time, OpenPGP has specified a series of [S2K mechanisms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-string-to-key-s2k-types-reg), following the current state of the art. Of the specified S2K mechanisms, two remain relevant today:
Over time, OpenPGP has specified different S2K [mechanisms to generate symmetric keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-string-to-key-s2k-types-reg), following the state of the art. Of these, two are recommended unconditionally, today:
- [Iterated and Salted S2K](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-iterated-and-salted-s2k), which OpenPGP version 4 implementations can handle
- [Argon2](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-argon2), which was newly added in OpenPGP version 6, and additionally protects the passphrase against brute-force attacks because it is memory-hard (which reduces the efficiency of attacks with specialised hardware)
- [Argon2](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-argon2), which was newly added in OpenPGP version 6. It is a memory-hard mechanism, which reduces the efficiency of brute-force attacks with specialised hardware.
- [Iterated and Salted S2K](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-iterated-and-salted-s2k), which OpenPGP version 4 implementations can handle.
### Encryption of private key material with a symmetric key
A third mechanism is allowed conditionally for generation. Decryption of private keys that use obsolete mechanisms is allowed.
The RFC refers to the mechanism that is used to *generate* a symmetric key from a passphrase with the term "String-to-Key (S2K) specifier" or "String-to-Key (S2K) specifier type."
### Using the symmetric key for encryption
So far, we've looked at generating a symmetric key from a passphrase. Following that, the symmetric key is used to encrypt or decrypt the OpenPGP private key material.
The RFC refers to the mechanism that is used to *apply* the symmetric key with the term "String-to-Key Usage (S2K usage)".
Different mechanisms are specified [for encryption of OpenPGP private key material](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-secret-key-encryption).
### Passphrase-protection acts per-component key
@ -97,46 +101,18 @@ The OpenPGP mechanism for protecting private key material applies individually t
- using different passphrases.
- Individual component keys may be stored in unprotected form, while others are protected.
However, usually, when creating a certificate, the user's software will use the same encryption mechanism and passphrase for all component keys. This might give the erroneous impression that all component private key material are internally encrypted in one monolithic operation, necessarily using only one passphrase.
However, usually, when creating a certificate, the user's software will use the same encryption mechanism and passphrase for all component keys. This might give the erroneous impression that all component private key material is internally encrypted in one monolithic operation, necessarily using only one passphrase.
But for example when adding new subkeys to a certificate at a later date, the user might choose to use a different passphrase. Or the user's software may choose a different encryption mechanism, e.g., based on updated best practices.
## Private key operations
(card-priv)=
## OpenPGP card for private keys
The core of private key operations doesn't require access to the whole certificate.
[OpenPGP card](https://en.wikipedia.org/wiki/OpenPGP_card) devices are a type of hardware security device.
While OpenPGP as a whole employs a broad range of cryptographic mechanisms, the set of operations that are performed in the core of a private key store are simple and very limited.
They are one popular way to handle OpenPGP private key material. Using an OpenPGP card is an alternative to directly handling private key material on the user's computer.
Specifically, an OpenPGP private key store implements two primitives:
1. Given private key material whose algorithm supports decryption, it can decrypt a *session key*.
2. Given private key material whose algorithm supports signing, it can calculate a *cryptographic signature* for a hash digest.
### Key store design options
Designs of private key subsystems in the OpenPGP space differ:
1. Some designs perform the primitive cryptographic operations in a separate backend, only using the cryptographic key material itself. This type of design matches well with general purpose hardware cryptographic devices (such as TPMs).
2. An OpenPGP private key subsystem may also require the additional metadata that is stored in the component key (the key creation time, for all keys, and in the case of keys that use ECDH algorithms: the KDF parameters).
3. Keeping a copy of full TSKs in the private key subsystem, and using those for private key operations.
Either way: An OpenPGP private key subsystem performs operations that only require the private cryptographic key material.
An independent concern is how key material is selected, when using the keystore. The fingerprint of the component key is an obvious option. This requirement can be solved by design 2, which allows calculation of component key fingerprints.
```{note}
Design 3, which involves keeping a copy of full TSKs in the private key subsystem can cause "split brain" problems.
For example, the private key store may contain a TSK, with outdated certificate metadata. The certificate may be considered expired, based on data in the TSK, while the copy of the same certificate in the local public key store might show an updated version where the expiration date has been extended[^tb-split].
This class of problem existed in GnuPG 1.x, which held separate copies of full TSKs in its private store component.
```
[^tb-split]: The current design of Thunderbird's OpenPGP subsystem can lead to users experiencing such issues.
### OpenPGP card for private keys
[OpenPGP card](https://en.wikipedia.org/wiki/OpenPGP_card) devices are a type of hardware security device. They are one popular way to handle OpenPGP private key material.
Hardware security devices, such as OpenPGP cards, are designed so that the user's computer never has direct access to the private key material. The goal is to make it impossible to exfiltrate the key material, even when a remote attacker has fully compromised the user's system.
OpenPGP card devices implement an open specification: [Functional Specification of the OpenPGP application on ISO Smart Card Operating Systems, Version 3.4.1](https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf). Multiple vendors produce devices that implement this specification, and there are a number of Free Software implementations (some of which can even be run on open hardware designs).
@ -148,11 +124,78 @@ OpenPGP card devices do not store a full OpenPGP certificate. Instead, they have
Note that explicitly stored fingerprints on OpenPGP cards are in contrast to how OpenPGP's format stores component keys: fingerprints are not explicitly stored, but calculated on the fly from the component key data.
## Private key operations
While OpenPGP as a whole employs a broad range of cryptographic mechanisms, the set of operations that are performed in the core of a private key store are simple and very limited.
Specifically, an OpenPGP private key store implements two primitives:
1. Given private key material whose algorithm supports decryption, it can decrypt a *session key*.
2. Given private key material whose algorithm supports signing, it can calculate a *cryptographic signature* for a hash digest.
All required operations can be performed with access to the component keys, including their private key material. That is, [Secret-Key packets](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-secret-key-packet-formats). Additional packets, such as binding signatures, are not required for the operations in a private key store.
(key-store-design)=
## Private key stores
### Design options
Designs of private key subsystems in the OpenPGP space differ:
1. Some designs perform the primitive cryptographic operations in a separate backend, only using the cryptographic key material itself. This type of design matches well with general purpose hardware cryptographic devices (such as TPMs).
2. An OpenPGP private key subsystem may be built around component keys - that is, the content of [Secret-Key packets](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-secret-key-packet-formats). These include metadata, which is required for some operations. ECDH operations, in particular, require metadata as KDF parameters.
3. Keeping a copy of full TSKs in the private key subsystem, and using those for private key operations.
Private key store operations require component keys, but do not require access to the rest of the certificate.
```{note}
The ECDH mechanism for decryption on an OpenPGP card produces the "shared secret". The unwrapping step happens in software, outside the card.
Design 3, which involves keeping a copy of full TSKs in the private key subsystem can cause "split brain" problems.
For example, the private key store may contain a TSK, with outdated certificate metadata. The certificate may be considered expired, based on data in the TSK, while the copy of the same certificate in the local public key store might show an updated version where the expiration date has been extended[^tb-split].
This class of problem existed in GnuPG 1.x, which held separate copies of full TSKs in its private store component.
```
## Details about the operation of an OpenPGP key store
[^tb-split]: The current design of Thunderbird's OpenPGP subsystem can lead to users experiencing such issues.
### Two tiers
At its core, an OpenPGP private key subsystem performs operations that only require the private cryptographic key material, as in design 1.
However, some operations require additional access to the metadata of the component key. Those operations can be considered supplementary to the core keystore operations, and don't involve the private key material, themselves. When implementing a key store based on hardware cryptographic devices, like [OpenPGP card](card-priv), its design will consist of two layers:
- One that deals immediately with private key material, and
- One that performs additional cryptographic operations, which don't directly use the private key material (in particular: [AES key wrap](https://www.rfc-editor.org/rfc/rfc3394.html) for ECDH).
```{note}
Decryption with ECC algorithms using ECDH in particular is a multi-step procedure.
Only one of these steps deals directly with private key material, and is performed by e.g. an OpenPGP card device. This step produces the "shared secret".
An additional ["AES key unwrap"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-ec-dh-algorithm-ecdh) step happens in software, outside the card. Also see "Advanced Encryption Standard (AES) Key Wrap Algorithm" [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394.html).
```
### Addressing individual keys
An independent design question is how key material is adressed, by users of the keystore.
The fingerprint of the individual component keys is one obvious option.
Depending on what backs the keystore, fingerprints are readily available, such as with software private keys, or OpenPGP card devices. In other cases, the key store needs to keep track of fingerprints by itself, e.g., when based on generic cryptographic hardware such as TPM.
### Assorted other duties
Additionally, a key store may want to keep track of devices that contain particular component keys. It may need to deal with secrets, such as passphrases of software keys, or PINs of OpenPGP card devices. It may need to notify the user that some interaction is required. For example, some OpenPGP card devices can require touch confirmation to authorize each cryptographic operation.
### Visualizing key store operations
#### Signing
```{admonition} TODO
:class: warning
write
```
```{admonition} VISUAL
:class: warning
@ -160,10 +203,9 @@ The ECDH mechanism for decryption on an OpenPGP card produces the "shared secret
show examples for the operations in a private key store.
- re-use the visual elements of the lowest level in the ch6 "how signatures are made" diagram (ch 6): "making a cryptographic signature from a hash digest"
- analogous: once we have a visual for the low level asymmetric decryption operation (in ch11), mirror it here
```
### Signing
#### Decryption
```{admonition} TODO
:class: warning
@ -171,33 +213,24 @@ show examples for the operations in a private key store.
write
```
### Decryption
```{admonition} TODO
```{admonition} VISUAL
:class: warning
write
show examples for the operations in a private key store.
- once we have a visual for the low level asymmetric decryption operation (in ch11), mirror it here
```
```{note}
Decryption with ECC algorithms, using ECDH, is a multi-step procedure. Only one of these steps is handled by the card.
The ECDH mechanism on the card produces a "shared secret" in compliance with the Elliptic Curve Key Agreement Scheme from Diffie-Hellman. Further processing (such as the key derivation function) happens in software.
<https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-ec-dh-algorithm-ecdh>
ECDH: Key Wrap Algorithm (RFC 3394)
<https://www.rfc-editor.org/rfc/rfc3394.html>
- [Decrypt unwrap in Sequoias ecdh.rs](https://gitlab.com/sequoia-pgp/sequoia/-/blob/main/openpgp/src/crypto/ecdh.rs?ref_type=heads#L120) should be a good place to start
```
## Advanced topics
### TSKs: Best practices S2K + S2K migration?
```{admonition} TODO
:class: warning
write
```
### The KOpenPGP attack
See [https://www.kopenpgp.com/](https://www.kopenpgp.com/)