14 KiB
Signatures over data
In OpenPGP, a {term}data signature
guarantees the {term}authenticity<Authentication>
and, implicitly, the integrity of certain data. Typical use cases of {term}data signatures<Data Signature>
include the {term}authentication
of software packages and emails.
"{term}Authenticity<Authentication>
" in this context means that the {term}data signature
was issued by {term}the entity controlling the signing key material<Certificate Holder>
. However,
it does not automatically signal if the expected party indeed controls the {term}signer
{term}certificate<OpenPGP Certificate>
. OpenPGP does offer mechanisms for strong {term}authentication
, connecting {term}certificates<OpenPGP Certificate>
to specific {term}identities<Identity>
. This verifies that the intended communication partner is indeed associated with the cryptographic {term}identity
behind the {term}signature<OpenPGP Signature Packet>
1.
{term}Data signatures<Data Signature>
can only be issued by {term}component keys<Component Key>
with the {term}signing<Signing Key Flag>
key flag.
Note that {term}data signatures<Data Signature>
are distinct from , which are used to form and maintain {term}certificates<OpenPGP Certificate>
, as well as to {term}certify<Certification>
{term}identities<Identity>
on {term}certificates<OpenPGP Certificate>
.
(data-signature-types)=
Signature types
{term}OpenPGP data signatures<Data Signature>
use one of two signature types:
- Binary signature ({term}
type ID<Signature Type ID>
0x00
): This is the standard {term}signature type
for binary data and is typically used for files or data streams. {term}Binary signatures<Binary Signature>
are calculated over the data without any modifications or transformations. - Text signature ({term}
type ID<Signature Type ID>
0x01
): Used for textual data, such as email bodies. When calculating a {term}text signature
, the data is first normalized by converting line endings into a canonical form (<CR><LF>
). This approach mitigates issues caused by platform-specific text encodings. This is especially important for detached and {term}cleartext signatures<Cleartext Signature>
, where the message file might undergo re-encoding between the creation and {term}verification
of the {term}signature<OpenPGP Signature Packet>
.
{term}Data signatures<Data Signature>
are generated by {term}hashing<Hash Digest>
the message content along with the {term}metadata
in the {term}OpenPGP signature packet
, and calculating a {term}cryptographic signature
over that {term}hash<Hash Digest>
. The resulting {term}cryptographic signature
is stored in the {term}signature packet<OpenPGP Signature Packet>
.
{term}Data signatures<Data Signature>
manifest in three distinct forms, which will be detailed in the subsequent section.
(forms-of-data-signatures)=
Forms of OpenPGP data signatures
{term}OpenPGP data signatures<Data Signature>
can be applied in three distinct forms2:
- {term}
Detached<Detached Signature>
: The OpenPGP signature exists as a separate entity, independent of the signed data. - {term}
Inline<Inline Signature>
: Both the original data and its corresponding {term}OpenPGP signature<OpenPGP Signature Packet>
are encapsulated within an {term}OpenPGP message
. - {term}
Cleartext signature
: A plaintext message and its {term}OpenPGP signature<OpenPGP Signature Packet>
coexist in a combined text format, preserving the readability of the original message.
Detached signatures
A {term}detached signature
is produced by calculating an {term}OpenPGP signature<OpenPGP Signature Packet>
over the data intended for signing. The original data remains unchanged, and the {term}OpenPGP signature<OpenPGP Signature Packet>
is stored as a standalone file. A {term}detached signature
file can be distributed alongside or independent of the original data. The {term}authenticity<Authentication>
and integrity of the original data file can be {term}verified<Verification>
by using the {term}detached signature
file.
This {term}signature<OpenPGP Signature Packet>
format is especially useful for signing software releases and other files where it is imperative that the content remains unaltered during the signing process.
(inline-signature)=
Inline signatures
An {term}inline signature
joins the signed data and its corresponding {term}data signature
into a single {term}OpenPGP message
.
This method is commonly used for signing or encrypting emails. Most email software capable of handling OpenPGP communications typically uses {term}inline signatures<Inline Signature>
.
Structure
There are two different constructions available to generate inline-signed messages:
- {term}
One-pass-signed messages<One-pass-signed Message>
are signed using one or more {term}one-pass signatures<One-pass Signature Packet>
- {term}
Prefixed-signed messages<Prefixed-signed Message>
have the actual signature(s) prefixed to the {term}OpenPGP message<OpenPGP Message>
.
A {term}one-pass-signed<One-pass-signed Message>
{term}OpenPGP message
consists of three segments:
-
One-pass signature packets: These one or more {term}
packets<Packet>
precede the signed data and enable {term}signature<OpenPGP Signature Packet>
computation in one pass. -
Literal data packet: This contains the original data (e.g., the body of a message), without additional interpretation or conversion.
-
{term}
Data signature packets<OpenPGP Signature Packet>
: These contain the {term}cryptographic signature
corresponding to the original data.
Less commonly used are {term}prefixed-signed messages<Prefixed-signed Message>
, where the {term}signature packet(s)<signature packet>
are simply prepended to the message.
Creation
To produce an {term}inline signature
, the {term}signer
processes the entirety of the data by reading from an input file and writing into an output {term}OpenPGP message
file. As the data is processed, the {term}signer
simultaneously calculates a {term}cryptographic signature
. This procedure results in the appending of a {term}data signature packet
to the output {term}OpenPGP message
file, where it can be efficiently stored.
For efficient {term}verification
, an application must understand how to handle the {term}literal data<Literal Data Packet>
prior to its reading. This requirement is addressed by the {term}one-pass signature packets<One-pass Signature Packet>
located at the beginning of {term}inline-signed<Inline Signature>
messages. These {term}packets<Packet>
include essential information such as the {term}fingerprint<OpenPGP Fingerprint>
of the {term}signing key<OpenPGP Component Key>
and the {term}hash<Hash Digest>
algorithm used for computing the {term}signature<OpenPGP Signature Packet>
's {term}hash digest
. This setup enables the verifier to process the data correctly and efficiently.
Strictly speaking, knowing just the hash algorithm would be sufficient to begin the verification process. However, having efficient access to the signer's fingerprint or key ID upfront allows OpenPGP software to fetch the signer's certificate(s) before processing the entirety of the - potentially large - signed data. This may, for example, involve downloading the certificate from a keyserver. In case fetching the signer's certificate(s) fails, or requires additional input from the user, it is better to signal the user about this before processing the data.
Verification
{term}Inline-signed<Inline Signature>
messages enable efficient {term}verification
in one pass, structured as follows:
-
Initiation with {term}
one-pass signature packets<One-pass Signature Packet>
: These {term}packets<Packet>
begin the {term}verification
process. They include the {term}signer
's {term}key ID
/{term}fingerprint<OpenPGP Fingerprint>
, essential for identifying the appropriate {term}public key<OpenPGP Certificate>
for signature {term}validation
. -
Processing the {term}
literal data packet
: This step involves {term}hashing<Hash Digest>
the literal data, preparing it for {term}signature<OpenPGP Signature Packet>
{term}verification
. -
{term}
Verifying<Verification>
{term}signature packets<OpenPGP Signature Packet>
: Located at the end of the message, these {term}packets<Packet>
are checked against the previously calculated {term}hash digest
.
Important to note, the {term}signer
's {term}public key<OpenPGP Certificate>
, critical for the final {term}verification
step, is not embedded in the message. Verifiers must acquire this {term}key
externally (e.g., from a {term}key server
) to authenticate the {term}signature<OpenPGP Signature Packet>
successfully.
(cleartext-signature)=
Cleartext signatures
The {term}Cleartext Signature Framework
(CSF) in OpenPGP accomplishes two primary objectives:
- maintaining the message in a human-readable cleartext format, accessible without OpenPGP-specific software
- incorporating an {term}
OpenPGP signature<OpenPGP Signature Packet>
for {term}authentication
by users with OpenPGP-compatible software
Example
The following is a detailed example of a {numref}cleartext
signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
hello world
-----BEGIN PGP SIGNATURE-----
wpgGARsKAAAAKQWCZT0vBCIhBtB7JOyRoU3SQKwtU+bIqeBUlJpBIi6nOFdu0Zyu
o9yZAAAAANqgIHAzoRTzu/7Zuxc8Izf4r3/qSCmBfDqWzTXqmVtsSBSHACka3qbN
eehqu8H6S0UK8V7yHbpVhExu9Hu72jWEzU/B0h9MR5gDhJPoWurx8YfyXBDsRS4y
r13/eqMN8kfCDw==
=Ks9w
-----END PGP SIGNATURE-----
This {term}signature<Cleartext Signature>
consists of two parts: a message ("hello world") and an ASCII-armored {term}OpenPGP signature<OpenPGP Signature Packet>
. The message is immediately comprehensible to a human reader, while the {term}signature<OpenPGP Signature Packet>
block allows for the message's {term}authenticity<Authentication>
{term}verification
via OpenPGP software.
Use case
{term}Cleartext signatures<Cleartext Signature>
combine the advantages of both {term}detached<Detached Signature>
and {term}inline signatures<Inline Signature>
:
-
Self-contained format: {term}
Cleartext signatures<Cleartext signature>
enable the message and its {term}signature<OpenPGP Signature Packet>
to be stored as a single file. -
Human readability: The message within a {term}
cleartext signature
remains accessible in a plain text format. This eliminates the need for specialized software to read the message content.
These features are particularly beneficial in scenarios where signed messages are managed semi-manually and where existing system infrastructure offers limited or no native support for OpenPGP in the workflow3.
Text transformations for cleartext signatures
The {term}cleartext signature framework
includes specific text normalization procedures to ensure the integrity and clarity of the message:
-
Escaping dashes: The framework implements a method of dash-escaped text within the message. Dash-escaping ensures that the parser correctly distinguishes between the armor headers, which are part of the {term}
signature<OpenPGP Signature Packet>
's structure, and any lines in the message that happen to start with a dash. -
Normalization of line endings: Consistent with the approach for any other text signature, a {term}
cleartext signature
is calculated on the text with normalized line endings (<CR><LF>
). This ensures that the {term}signature<OpenPGP Signature Packet>
remains valid regardless of the text format of the receiving {term}implementation<OpenPGP Implementation>
.
Pitfalls
Despite their widespread adoption, {term}cleartext signatures<Cleartext Signature>
have their limitations and are sometimes viewed as a "legacy method"4. The {term}RFC
details the pitfalls of cleartext signatures, such as incompatibility with semantically meaningful whitespace, challenges with large messages, and security vulnerabilities related to misleading Hash header manipulations. Given these issues, safer alternatives like {term}inline<Inline Signature>
and {term}detached signature
forms are advised.
-
Other signing solutions, like signify, focus on pure signing without strong {term}
authentication
of the {term}signer
's {term}identity
. ↩︎ -
These three forms of {term}
signature<OpenPGP Signature Packet>
application align with GnuPG's--detach-sign
,--sign
, and--clearsign
command options. ↩︎ -
An illustrative example is the workflow adopted by Arch Linux to {term}
certify<Certification>
{term}User IDs<User ID>
of new packagers. This process relies on cleartext signed statements from existing packagers. These signed statements are stored as attachments in an issue tracking system for later inspection. The advantage of this approach lies in the convenience of having the message and signature in a single file, which simplifies manual handling. Based on the vouches in these {term}cleartext signed<Cleartext Signature>
messages and an email confirmation from the new packager, the main key operators can issue {term}OpenPGP third-party certifications<Third-party Identity Certification>
. ↩︎ -
https://lists.gnupg.org/pipermail/gnupg-devel/2023-November/035428.html ↩︎