openpgp-notes/book/source/05-private.md
2023-12-01 19:47:16 +01:00

18 KiB

(private_key_chapter)=

Managing private key material in OpenPGP

Overview of private keys

This chapter discusses the handling of private key material within OpenPGP.

Private key material is associated with component keys, which are integral parts of OpenPGP certificates. For a discussion of packet structure internals, see the chapter {ref}zoom_private.

"Certificates" and "private keys" explained

Recall that in this document, the term OpenPGP certificate refers to what are commonly known as "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 focuses on the corresponding counterpart to the elements of certificates: the private key material of component keys.

In this documentation, we treat the private key material as logically separate from the OpenPGP certificate. Operations that use private key material are typically managed by a separate subsystem. It is useful to view OpenPGP certificates and the associated private key material as related but distinct elements1:

:name: fig-openpgp-certificate-with-private-key-store
:alt: A diagram on a white background showing an OpenPGP certificate and a private keystore. Gray dotted lines connect the green public key symbols of the OpenPGP certificate to red dotted private key symbols in the private keystore.

An OpenPGP certificate, with the associated private key material handled in a separate subsystem.

In certain cases, an exception arises where the cryptographic private key material is integrated into the same OpenPGP framing format as the certificate. This is specifically done in the context of transferable secret keys (TSKs).

Transferable secret key format

Sometimes it is useful to handle OpenPGP certificates combined with private key material in the form of a transferable secret key (TSK). A TSK is a serialized format that combines OpenPGP certificate data with its connected private key material, stored in a single file.

:name: fig-transferable-secret-key
:alt: A box on a white background titled "transferable secret key." It resembles the figure depicting an OpenPGP certificate, except that in each component key box, below the green public key symbol,  the red-dotted private key symbol is also shown.

OpenPGP certificate with integrated private key material, as a TSK

The TSK format is particularly useful for backups of OpenPGP key material or transferring a key to a different computer2. For insights into the packet structure of a TSK, see the chapter {ref}zoom_private.

:class: note

Transferable secret keys are sometimes colloquially referred to as "OpenPGP private keys."

Historically, the concept of TSKs, which combine all elements of an OpenPGP certificate with the associated private key material, has sometimes been conflated with OpenPGP private key operations. However, it is more accurate to view TSKs as a specialized format for storage and transport, rather than as a data structure for use in a keystore. For further details, see {ref}key-store-design.

(encrypted_secrets)=

Protecting keys with passphrases

In the OpenPGP format, private key material can be optionally protected with a passphrase.

This method proves effective in scenarios where an unauthorized party obtains the OpenPGP key data but does not know the passphrase. Such a safeguard renders the key unusable to the attacker, effectively protecting it against unauthorized access or use.

Transforming passphrases into symmetric keys

When protecting private key material in OpenPGP, a symmetric key is derived from the user's passphrase. This derived key is then used to protect the OpenPGP private key data.

To facilitate this, the OpenPGP standard defines a set of mechanisms known as string-to-key (S2K). S2K mechanisms are used to generate high-entropy symmetric encryption keys from lower-entropy passphrases, using a key derivation function (KDF).

:name: fig-passphrase-using-s2k
:alt: A diagram on a white background titled "Converting a passphrase into a symmetric key." On the left is a light-yellow box with dotted-yellow borders framing the phrase "correct horse battery staple." A dotted yellow line falls below the box to the term "passphrase." To the right of the box is a light-green arrow with green-dotted borders and the text "S2K mechanism (string-to-key). The arrow points to its right, where a yellow symmetric key symbol is shown.

Deriving a symmetric key from a passphrase

This symmetric key is used to protect the private key material it is in a passive state, for example, when stored on disk. To use a passphrase-protected OpenPGP private key, it is first decrypted using the symmetric key and then used for private key operations, remaining temporarily unlocked in memory.

Mechanisms for symmetric key generation

Over time, OpenPGP has evolved to include various S2K mechanisms for generating symmetric keys, in line with advancements in cryptographic practices. Currently, two mechanisms are universally recommended:

  • Argon2: Introduced in OpenPGP version 6, Argon2 is a memory-hard mechanism designed to reduce the efficiency of brute-force attacks using specialized hardware.
  • Iterated and Salted S2K: This mechanism is a staple with OpenPGP version 4 implementations.

A third mechanism is conditionally allowed for key generation. Decryption of private keys that use obsolete mechanisms is also allowed.

The RFC uses the terms "String-to-Key (S2K) specifier" or "String-to-Key (S2K) specifier type" for mechanisms used to generate a symmetric key from a passphrase.

Using symmetric keys for encryption

The generation of a symmetric key from a passphrase leads to its subsequent use in encrypting or decrypting OpenPGP private key material.

The RFC uses the term "String-to-Key Usage (S2K usage)" for the mechanism used to apply the symmetric key.

Different mechanisms are specified for encryption of OpenPGP private key material.

Component-based passphrase protection

The OpenPGP mechanism for protecting private key material applies individually to each component key:

  • Private key material for individual component keys within a single certificate can be protected with different mechanisms or passphrases.
  • Individual component keys may be stored in unprotected form, while others are secured.

Commonly, 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 encrypted in one, monolithic operation using a single passphrase.

However, variations are possible, such as when adding new subkeys to an existing certificate. In such cases, a user might choose a different passphrase, or the software might select a different encryption mechanism, for instance, for updated best practices.

(card-priv)=

OpenPGP cards for private keys

OpenPGP cards represent a category of hardware security devices specifically designed to handle OpenPGP private key material. These cards offer an alternative to directly managing private key material on the user's computer.

Hardware security devices, such as OpenPGP cards, are designed to prevent the user's computer from 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 cards adhere to an open specification detailed in the Functional Specification of the OpenPGP application on ISO Smart Card Operating Systems, Version 3.4.1. This specification has been implemented by multiple vendors across various devices, with several Free Software versions available, some of which are compatible with open hardware designs.

Effectively, the OpenPGP card specification outlines one model for a private keystore subsystem. OpenPGP cards do not store a full OpenPGP certificate. Instead, they have three distinct "key slots" designated for signing, decryption, and authentication. Each key slot stores the data of one component key3, including its cryptographic private key material. Additionally, OpenPGP cards explicitly store the fingerprint of each component key within the corresponding key slot.

Notably, the practice of explicitly storing fingerprints on OpenPGP cards contrasts with the general OpenPGP format, where fingerprints of component keys are not stored but are instead dynamically calculated from the key data.

Private key operations

Although OpenPGP encompasses a broad range of cryptographic mechanisms, the set of operations performed within the core of a private keystore are simple and very limited.

Specifically, an OpenPGP private keystore 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.

These essential operations require access only to the component keys and their associated private key material, specifically Secret-Key packets. Additional packets, such as binding signatures, are not required.

Visualizing a signing operation

:class: warning

write
:class: warning

show examples for the operations in a private keystore.

- reuse 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"

Visualizing a decryption operation

:class: warning

write
:class: warning

show examples for the operations in a private keystore.

- once we have a visual for the low level asymmetric decryption operation (in ch11), mirror it here

Advanced topics

(key-store-design)=

Private keystores

This section examines the diverse architectures and operational mechanics of private keystores in OpenPGP. It focuses on the various design choices, their functional implications, and how they contribute to the secure management of private key material.

Design variations

The design of private key subsystems within the OpenPGP framework varies, offering different approaches to cryptographic operations:

  1. Separate backend operations: Some designs execute the primitive cryptographic operations in a separate backend, using only the cryptographic key material. This approach is particularly compatible with general purpose hardware cryptographic devices, such as trusted platform modules (TPMs).
  2. Component key-based systems: An OpenPGP private key subsystem may be built around component keys, specifically the content of Secret-Key packets. These packets contain metadata that is required for some operations. ECDH operations, in particular, require metadata as KDF parameters.
  3. Full transferable secret keys: Some designs maintain copies of full TSKs in the private key subsystem, leveraging these for private key operations.

While private keystore operations require component keys, they do not require access to the entire OpenPGP certificate.

The third design option, involving the storage of full TSKs in the private key subsystem, can cause "split brain" problems.

For example, a private keystore might contain a TSK with outdated certificate metadata, marking the certificate as expired, while the updated version in the local public keystore could indicate an extended expiration date. 

This problem was notably present in GnuPG 1.x, which held separate TSK copies in its private store component. Similarly, the current design of Thunderbird's OpenPGP subsystem can lead to users experiencing such issues.

Two-tier architecture

At its core, an OpenPGP private key subsystem performs operations requiring only the private cryptographic key material, akin to the "separate backend operations" model described above.

However, the subsystem also supports operations that require additional access to the metadata of the component key. These operations, supplementary to the core keystore operations, do not involve the private key material.

When implementing a keystore based on hardware cryptographic devices like OpenPGP card, its design will consist of two layers:

  • core layer: directly handles private key material, and
  • supplementary layer: performs additional cryptographic operations that don't directly use the private key material, such as AES key wrap for ECDH.
 The decryption process using ECC algorithms, especially ECDH, has multiple steps. The initial step, potentially performed by devices such as OpenPGP cards, directly uses private key material to produce a "shared secret." Following this, operations like ["AES key unwrap"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-ec-dh-algorithm-ecdh) are conducted in software outside the hardware device. 
 
 Further details on this process can be found in the "Advanced Encryption Standard (AES) Key Wrap Algorithm" [RFC 3394](https://www.rfc-editor.org/rfc/rfc3394.html).

Addressing individual keys

A critical aspect of private keystore design involves determining how users address individual keys.

One common method is using the fingerprint of each component key. The availability of these fingerprints, however, depends on the underlying technology of the keystore. For instance, in software-based private keystores or OpenPGP cards, fingerprints of component keys are usually readily available. Keystores relying on generic cryptographic hardware, like TPMs, need to implement their own mechanisms for tracking and managing the fingerprints of each key.

Additional keystore duties

In addition to key management, a keystore often involves various supplementary functions:

  • Tracking devices: Keystores may track which devices contain particular component keys.

  • Handling secrets: This involves the management of sensitive information such as passphrases for software keys or PINs for OpenPGP cards.

  • User interaction alerts: Keystores might also need to prompt users for necessary interactions during certain operations. For example, OpenPGP cards may require user touch confirmation to authorize each cryptographic action.

TSKs: Best practices S2K + S2K migration?

:class: warning

write

Understanding key overwriting (KO) attacks

OpenPGP is subject to specific vulnerabilities known as key overwriting (KO) attacks. These attacks exploit weaknesses in how encrypted private keys or their metadata are handled, potentially leading to the leakage of secret data when a key is used. The core issue lies in OpenPGP's handling of Secret-Key packets, where corruption of the public, non-encrypted fields of these packets can cause the correct private key material to be used with corrupted public key parameters. This mismatch can result in private key leakage.

Understanding KO attacks is crucial due to their potential to compromise the integrity and confidentiality of encrypted communications. KO attacks highlight the necessity for robust key validation procedures and the dangers of storing keys in insecure environments. As OpenPGP application developers, you should be aware of these risks to ensure the secure management of keys and to implement appropriate countermeasures.

For comprehensive information on KO attacks, including background, attack vectors, countermeasures, and technical analyses, visit KOpenPGP.com. It is based on the paper "Victory by KO: Attacking OpenPGP Using Key Overwriting" written by Lara Bruseghini, Daniel Huigens, and Kenneth G. Paterson for the Proceedings of ACM Conference on Computer and Communications Security, Los Angeles, November 2022.


  1. The distinction between certificates (which combine public key material and identity information) and private key material is similarly made in the data model of PKCS #11 cryptographic systems. ↩︎

  2. For example, in GnuPG, an OpenPGP key can be exported in (armored) TSK format using the following command: gpg --export-secret-key --armor <fingerprint>. ↩︎

  3. In the case of ECDH keys, the KDF parameters (hash function ID and a symmetric encryption algorithm ID) are not stored on the OpenPGP card. This is considered a flaw in the OpenPGP card specification. These missing parameters can be handled in two ways by OpenPGP software on the host computer: either by consulting a copy of the component key (e.g., by inspecting a copy of the certificate) or by deducing the missing KDF parameters from the stored OpenPGP fingerprint on the card. ↩︎