RFC 1991

PGP Message Exchange Formats

๐Ÿ“… published August 1996, from ietf

RFC 1991: PGP Message Exchange Formats โœจ

Okay bestie, here are the deets ๐ŸŽ€

  • RFC number: 1991
  • Title: PGP Message Exchange Formats
  • Series: Network Working Group
  • Authors: D. Atkins (MIT), W. Stallings (Comp-Comm Consulting), and P. Zimmermann (Boulder Software Engineering)
  • Category: Informational
  • Date: August 1996
  • Obsoletes / Updates: none listed in the header, so it doesn't obsolete or update any other RFC ๐Ÿฆ‹

Status of This Memo ๐Ÿ“œ

This memo is here to give the Internet community some info ๐Ÿ’–. It does not specify an Internet standard of any kind, so it's not a rulebook. Distribution is unlimited, so share it wherever you want ๐ŸŒˆ.

Table of Contents ๐Ÿ“‘

   1.    Introduction............................................2
   2.    PGP Services............................................2
   2.1   Digital signature.......................................3
   2.2   Confidentiality.........................................3
   2.3   Compression.............................................4
   2.4   Radix-64 conversion.....................................4
   2.4.1 ASCII Armor Formats.....................................5
   3.    Data Element Formats....................................6
   3.1   Byte strings............................................6
   3.2   Whole number fields.....................................7
   3.3   Multiprecision fields...................................7
   3.4   String fields...........................................8
   3.5   Time fields.............................................8
   4.    Common Fields...........................................8
   4.1   Packet structure fields.................................8
   4.2   Number ID fields.......................................10
   4.3   Version fields.........................................10
   5.    Packets................................................10
   5.1   Overview...............................................10
   5.2   General Packet Structure...............................11
   5.2.1 Message component......................................11
   5.2.2 Signature component....................................11
   5.2.3 Session key component..................................11
   6.    PGP Packet Types.......................................12
   6.1   Literal data packets...................................12
   6.2   Signature packets......................................13
   6.2.1 Message-digest-related fields..........................14
   6.2.2 Public-key-related fields..............................15
   6.2.3 RSA signatures.........................................16
   6.2.4 Miscellaneous fields...................................16
   6.3   Compressed data packets................................17
   6.4   Conventional-key-encrypted data packets................17
   6.4.1 Conventional-encryption type byte......................18
   6.5   Public-key-encrypted packets...........................18
   6.5.1 RSA-encrypted data encryption key (DEK)................19
   6.6   Public-key Packets.....................................19
   6.7   User ID packets........................................20
   7.    Transferable Public Keys...............................20
   8.    Acknowledgments........................................20
   9.    Security Considerations................................21
   10.   Authors' Addresses.....................................21

1. Introduction ๐ŸŒธ

Okay so PGP (Pretty Good Privacy) mixes public-key and conventional encryption to keep electronic mail messages and data files secure ๐Ÿ”. The services it gives you are confidentiality and digital signatures, and it's widely used all over the global computer community. This doc explains the format of "PGP files", which are basically messages that have been encrypted and/or signed with PGP ๐Ÿ’….

PGP was created by Philip Zimmermann and first released in 1991 as Version 1.0 ๐ŸŽ‰. After that, an all-volunteer collaborative effort kept building it, all under the design guidance of Philip Zimmermann. PGP and Pretty Good Privacy are trademarks of Philip Zimmermann, so that's his name on the branding ๐Ÿ‘‘.

This doc describes versions 2.x of PGP. Versions 2.6 and 2.7 conform to this spec, and Version 2.3 conforms with minor differences ๐Ÿงš.

A new release called PGP 3.0 was anticipated in 1995. The goal was to stay upwardly compatible with version 2.x as much as possible. At a minimum, PGP 3.0 would be able to read messages and signatures made by version 2.x ๐Ÿฆ‹.

2. PGP Services ๐Ÿ’œ

PGP gives you four services related to the format of messages and data files: digital signature, confidentiality, compression, and radix-64 conversion โœจ.

2.1 Digital signature

The digital signature service uses a hash code (also called a message digest) algorithm and a public-key encryption algorithm together. Here's how it goes ๐Ÿง :

  • first, the sender creates a message ๐Ÿ’Œ
  • the sending PGP generates a hash code of the message
  • the sending PGP encrypts the hash code using the sender's private key
  • the encrypted hash code is prepended to the message
  • the receiving PGP decrypts the hash code using the sender's public key
  • the receiving PGP generates a new hash code for the received message and compares it to the decrypted hash code. If the two match, the message is accepted as authentic โœ…

Signatures usually hang out attached to the message or file they sign, but that's not always the case, because detached signatures are supported too ๐Ÿ™ˆ. A detached signature can be stored and sent separately from the message it signs, and that's super useful. A user might want a separate signature log of every message they sent or received. A detached signature of an executable program can catch a virus infection later on ๐Ÿฆ . And detached signatures are clutch when more than one party has to sign a document, like a legal contract. Each person's signature is independent and only applies to the document. Otherwise the signatures would have to be nested, with the second signer signing both the document and the first signature, and so on, which is a whole mess ๐Ÿ’€.

2.2 Confidentiality

PGP keeps things confidential by encrypting messages before they get sent, or data files before they get stored locally, using conventional encryption ๐Ÿ”’. Here's the iconic part: each conventional key gets used only once. A new key is generated as a random 128-bit number for each message ๐ŸŽฒ. Since it's a one-and-done key, the session key is bound to the message and sent along with it. To keep that key safe, it gets encrypted with the receiver's public key ๐Ÿ—๏ธ. The flow looks like this:

  • the sender creates a message
  • the sending PGP generates a random number to be used as a session key for this message only
  • the sending PGP encrypts the message using the session key
  • the session key is encrypted using the recipient's public key and prepended to the encrypted message
  • the receiving PGP decrypts the session key using the recipient's private key
  • the receiving PGP decrypts the message using the session key

Both digital signature and confidentiality services can be applied to the same message ๐Ÿ‘ฏโ€โ™€๏ธ. First, a signature is generated for the message and prepended to it. Then the message plus signature gets encrypted using a conventional session key. Finally, the session key is encrypted with public-key encryption and prepended to the encrypted block. Main character energy ๐Ÿ‘‘.

2.3 Compression

By default, PGP compresses the message after applying the signature but before encrypting it ๐Ÿ—œ๏ธ. The order matters, so keep it in mind ๐Ÿ’….

2.4 Radix-64 conversion

When PGP is in use, part of the block being sent is usually encrypted ๐Ÿ”. If only the signature service is used, then the message digest gets encrypted with the sender's private key. If the confidentiality service is used, the message plus signature (if there is one) gets encrypted with a one-time conventional key. So part or all of the result is a stream of arbitrary 8-bit bytes ๐ŸŒ€. The problem is that lots of electronic mail systems only allow blocks made of ASCII text ๐Ÿ™ƒ. To fix that, PGP converts the raw 8-bit binary stream into a stream of printable ASCII characters, and that's called ASCII Armor ๐Ÿ›ก๏ธ.

The scheme for this is radix-64 conversion. Each group of three bytes of binary data gets mapped into 4 ASCII characters. The format also appends a CRC to detect transmission errors ๐Ÿ”. This radix-64 conversion, also called Ascii Armor, is a wrapper around the binary PGP messages, and it protects them during transmission over non-binary channels, like Internet Email ๐Ÿ“ง.

The table below shows the mapping. The characters are the upper- and lower-case letters, the digits 0 through 9, and the characters + and /. The carriage-return and linefeed characters aren't used in the conversion, and neither is the tab or any other character the mail system might change. The result is a text file that is "immune" to the modifications mail systems inflict ๐Ÿ›ก๏ธโœจ.

6-bit character   6-bit character   6-bit character   6-bit character
value encoding  value  encoding    value   encoding    value encoding
0        A        16        Q        32        g        48        w
1        B        17        R        33        h        49        x
2        C        18        S        34        i        50        y
3        D        19        T        35        j        51        z
4        E        20        U        36        k        52        0
5        F        21        V        37        l        53        1
6        G        22        W        38        m        54        2
7        H        23        X        39        n        55        3
8        I        24        Y        40        o        56        4
9        J        25        Z        41        p        57        5
1        K        26        a        42        q        58        6
11       L        27        b        43        r        59        7
12       M        28        c        44        s        60        8
13       N        29        d        45        t        61        9
14       O        30        e        46        u        62        +
15       P        31        f        47        v        63        /
                                                     (pad)       =

It's possible to use PGP to convert any arbitrary file to ASCII Armor ๐ŸŽ€. When you do that, PGP tries to compress the data before converting it to Radix-64 ๐Ÿซถ.

2.4.1 ASCII Armor Formats โœจ

okay so when PGP wraps data up in ASCII Armor ๐ŸŽ€, it puts specific headers around it so PGP can rebuild the data at a future time ๐Ÿ’…. the headers also tell you what kind of data is tucked inside, which is literally so helpful ๐Ÿฅน

ASCII Armor is made by smooshing these pieces together:

  • An Armor Headerline, matching the kind of data
  • Armor Headers
  • A blank line
  • The ASCII-Armored data
  • An Armor Checksum
  • The Armor Tail (which depends on the Armor Headerline).

An Armor Headerline is the right headerline text with five (5) dashes (-) on each side of it ๐Ÿงš. which text you get depends on what type of data is being armored and how it's being encoded. the headerline texts are:

BEGIN PGP MESSAGE -- used for signed, encrypted, or compressed files
BEGIN PGP PUBLIC KEY BLOCK -- used for transferring public keys
BEGIN PGP MESSAGE, PART X/Y -- used for multi-part messages, where
                                the armor is split amongst Y files,
                                and this is the Xth file out of Y.

the Armor Headers are pairs of strings that can give the user or the receiving PGP program some info about how to decode or use the message ๐Ÿ“. they're part of the armor, not part of the message, so they SHOULD NOT be used to convey anything important, since they can be changed in transport ๐Ÿ™ˆ. not the place for your secrets, bestie.

the format of an Armor Header is a key-value pair, like the encoding of RFC-822 headers ๐ŸŒธ. PGP SHOULD consider improperly formatted Armor Headers to be corruption of the ASCII Armor ๐Ÿ’€. unknown Keys SHOULD be reported to the user, but as long as the RFC-822 formatting is correct, PGP SHOULD continue to process the message โœจ. the Keys defined right now are "Version" and "Comment", which cover the PGP Version used to encode the message and a user-defined comment ๐Ÿฆ‹.

the Armor Checksum is a 24-bit CRC converted to four bytes of radix-64 encoding, with an equal-sign (=) stuck in front of the four-byte code ๐Ÿ”ฅ. the CRC uses the generator 0x864CFB and an initialization of 0xB704CE. the accumulation happens on the data before it gets converted to radix-64, not on the converted data ๐Ÿง . if you want more on CRC functions, the reader is asked to look at chapter 19 of the book "C Programmer's Guide to Serial Communications," by Joe Campbell ๐Ÿ“š.

the Armor Tail is built the same way as the Armor Headerline, except the string "BEGIN" gets swapped for "END" ๐ŸŒˆ. ta-da, the whole thing is wrapped up nicely.


3. Data Element Formats โœจ

3.1 Byte strings

okay so the objects in this document are all "byte strings" ๐Ÿ“. a byte string is a finite sequence of bytes. when you concatenate byte string X of length M with byte string Y of length N, you get a byte string Z of length M + N. the first M bytes of Z are the bytes of X in the same order, and the remaining N bytes of Z are the bytes of Y in the same order ๐Ÿ’–.

literal byte strings are written left to right, with pairs of hex nibbles separated by spaces, all wrapped in angle brackets. for instance, <05 ff 07> is a byte string of length 3 whose bytes have numeric values 5, 255, and 7 in that order ๐ŸŽ€. all numbers in this document outside angle brackets are written in decimal ๐Ÿ”ข.

the byte string of length 0 is called "empty" and written <> ๐Ÿซง.

3.2 Whole number fields

Purpose. a whole number field can represent any nonnegative integer, in a format where the field length is known in advance โœจ.

Definition. a whole number field is any byte string. it's stored in radix-256 MSB-first format ๐Ÿงš. so a whole number field of length N with bytes b_0 b_1 ... b_{N-2} b_{N-1} in that order has this value:

      b_0 * 256^{N-1} + b_1 * 256^{N-2} + ... + b_{N-2} * 256 + b_{N-1}.

Examples. the byte string <00 0D 64 11 00 00> is a valid whole number field with value 57513410560. the byte string <FF> is a valid whole number field with value 255. the byte string <00 00> is a valid whole number field with value 0. and the empty byte string <> is a valid whole number field with value 0 ๐Ÿฅฐ.

3.3 Multiprecision fields

Purpose. a multiprecision field can represent any nonnegative integer which is not too large ๐ŸŒธ. the field length doesn't need to be known in advance, and these fields are designed to waste very little space: a small integer uses a short field ๐Ÿ’….

Definition. a multiprecision field is the concatenation of two fields:

  • (a) a whole number field of length 2, with value B;
  • (b) a whole number field, with value V.

field (b) is of length [(B+7)/8], i.e., the greatest integer which is no larger than (B+7)/8. the value of the multiprecision field is defined to be V. V MUST be between 2^{B-1} and 2^B - 1 inclusive. in other words, B MUST be exactly the number of significant bits in V ๐Ÿง .

some implementations may limit the possible range of B. the implementor MUST document which values of B are allowed by an implementation ๐Ÿ“.

Examples. the byte string <00 00> is a valid multiprecision integer with value 0. the byte string <00 03 05> is a valid multiprecision field with value 5. the byte strings <00 03 85> and <00 00 00> are NOT valid multiprecision fields ๐Ÿ™…. the former is invalid because <85> has 8 significant bits, not 3; the latter is invalid because the second field has too many bytes of data for the value of the first field ๐Ÿ’€. the byte string <00 09 01 ff> is a valid multiprecision field with value 511 ๐Ÿ”ฅ.

and this one is giving main character energy ๐Ÿ‘‘. the following byte string is a valid multiprecision field with value 2^255 + 7:

<01 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07>

3.4 String fields

Purpose. a string field represents any sequence of bytes of length between 0 and 255 inclusive ๐ŸŽ€. the length doesn't need to be known in advance. by convention, the content of a string field is normally interpreted as ASCII codes when it gets displayed ๐Ÿ”ค.

Definition. a string field is the concatenation of the following:

  • (a) a whole number field of length 1, with value L;
  • (b) a byte string of length L.

the content of the string field is defined to be field (b) ๐Ÿซถ.

Examples. <05 48 45 4c 4c 4f> is a valid string field which would normally be displayed as the string HELLO. <00> is a valid string field which would normally be displayed as the empty string. and <01 00> is also a valid string field ๐Ÿ’œ.

3.5 Time fields

Purpose. a time field represents the number of seconds elapsed since 1970 Jan 1 00:00:00 GMT. it's compatible with the usual representation of times under UNIX โฐ.

Definition. a time field is a whole number field of length 4, with value V. the time represented by the time field is the one-second interval beginning V seconds after 1970 Jan 1 00:00:00 GMT ๐Ÿฆ‹.


4. Common Fields โœจ

this section defines fields found in more than one packet format ๐Ÿซง.

4.1 Packet structure fields

Purpose. the packet structure field tells different types of packets apart, and it indicates the length of packets ๐Ÿงš.

Definition. a packet structure field is a byte string of length 1, 2, 3, or 5 ๐Ÿ’…. its first byte is the cipher type byte (CTB), with bits labeled 76543210, where 7 is the most significant bit and 0 is the least significant bit. as shown below, the length of the packet structure field is determined by the CTB ๐Ÿ”ฅ.

CTB bits 76 have values listed in the following table:

10 - normal CTB
11 - reserved for future experimental work
all others - reserved

CTB bits 5432, the "packet type bits", have values listed in the following table:

0001 - public-key-encrypted packet
0010 - signature packet
0101 - secret-key certificate packet
0110 - public-key certificate packet
1000 - compressed data packet
1001 - conventional-key-encrypted packet
1011 - literal data packet
1100 - keyring trust packet
1101 - user id packet
1110 - comment packet     (*)
all others - reserved

CTB bits 10, the "packet-length length bits", have values listed in the following table:

00 - 1-byte packet-length field
01 - 2-byte packet-length field
10 - 4-byte packet-length field
11 - no packet length supplied, unknown packet length

as this table shows, depending on the packet-length length bits, the remaining 1, 2, 4, or 0 bytes of the packet structure field are a "packet-length field" ๐Ÿ“. the packet-length field is a whole number field, and its value is defined to be the value of that whole number field โœจ.

a value of 11 is currently used in one place: on compressed data ๐ŸŒท. so a compressed data block currently looks like <A3 01 . . .>, where <A3>, binary 10 1000 11, is an indefinite-length packet ๐Ÿง . the proper interpretation is "until the end of the enclosing structure," although it SHOULD never appear outermost (where the enclosing structure is a file) ๐Ÿ™ˆ.

options marked with an asterisk (*) are not implemented yet, and PGP 2.6.2 will never output this packet type ๐Ÿšซ.

4.2 Number ID fields

Purpose. the ID of a whole number is its 64 least significant bits ๐Ÿ”‘. the ID is a convenient way to tell big numbers apart, like keys, without having to transmit the number itself. so a number that may be hundreds or thousands of decimal digits long can be identified with a 64-bit identifier ๐ŸŒˆ. two keys may have the same ID by chance or by malice, though the probability that two large keys chosen at random would share an ID is extremely small ๐Ÿค.

Definition. a number ID field is a whole number field of length 8. the value of the number ID field is defined to be the value of the whole number field ๐Ÿ’–.

4.3 Version fields

many packet types include a version number as the first byte of the body ๐ŸŽ€. the format and meaning of the body depend on that version number. more versions of packets, with new version numbers, may be defined in the future ๐Ÿ”ฎ. an implementation need not support every version of each packet type. however, the implementor MUST document which versions of each packet type are supported by the implementation ๐Ÿ“.

a version number of 2 or 3 is currently allowed for each packet format ๐Ÿซถ. new versions will probably be numbered sequentially up from 3. for backwards compatibility, implementations will usually be expected to support version N of a packet whenever they support version N+1 ๐Ÿ’…. version 255 MAY be used for experimental purposes ๐Ÿงช.


5. Packets โœจ

5.1 Overview

a packet is a digital envelope with data inside ๐Ÿ’Œ. a PGP file, by definition, is the concatenation of one or more packets. on top of that, one or more of the packets in a file may be transformed using encryption, compression, or radix-64 conversion ๐Ÿ”.

a packet is the concatenation of the following:

  • (a) a packet structure field;
  • (b) a byte string of some length N.

byte string (b) is called the "body" of the packet. the value of the packet-length field inside the packet structure field (a) MUST equal N, the length of the body ๐Ÿ“.

other characteristics of the packet are determined by the type of the packet. see the definitions of particular packet types for further details. the CTB packet-type bits inside the packet structure always indicate the packet type ๐Ÿฆ‹.

and here's the fun part ๐Ÿช†: packets may be nested, so one digital envelope may be placed inside another. for example, a conventional-key-encrypted packet contains a disguised packet, which in turn might be a compressed data packet ๐Ÿ’œ.

5.2. General packet structure โœจ

okay bestie, so a pgp file is basically three pieces: a message component, a signature component (optional), and a session key component (optional) ๐ŸŽ€

5.2.1. Message component

the message component holds the actual data you want to store or send, plus a header full of control info that PGP makes for it ๐Ÿ’– it's a single literal data packet, so it's very simple and very cute ๐ŸŒธ

5.2.2. Signature component

this is the signature of the message component ๐Ÿ” it's made from a hash code of the message component plus the public key of the sending PGP entity. it's a single signature packet.

if the default compression option gets picked, then the literal data packet and the signature packet get squished together into one compressed data packet ๐Ÿ—œ๏ธ main character compression moment ๐Ÿ’…

5.2.3. Session key component

this one has the encrypted session key and the ID of the recipient's public key that the sender used to encrypt that session key ๐Ÿ—๏ธ there's one public-key-encrypted packet for each recipient of the message, so everyone gets their own lock ๐Ÿ”‘

if compression was used, conventional encryption gets applied to the compressed data packet (the one made from compressing the signature packet and the literal data packet) ๐Ÿง otherwise, conventional encryption goes on the block made of the signature packet and the literal data packet. either way, the ciphertext is called a conventional-key-encrypted data packet, which is a mouthful but iconic ๐Ÿซถ


6. PGP Packet Types ๐Ÿ‘‘

PGP includes these types of packets:

  • literal data packet
  • signature packet
  • compressed data packet
  • conventional-key-encrypted data packet
  • public-key-encrypted packet
  • public-key packet
  • User ID packet

6.1. Literal data packets ๐Ÿ“ฆ

Purpose. a literal data packet is the lowest level of contents inside a digital envelope ๐Ÿ’Œ the data inside it is not subject to any further interpretation by PGP, so PGP just hands it over as-is, no drama ๐ŸŒˆ

Definition. a literal data packet is the concatenation of these fields:

  • (a) a packet structure field;
  • (b) a byte, giving a mode;
  • (c) a string field, giving a filename;
  • (d) a time field;
  • (e) a byte string of literal data.

fields (b), (c), and (d) are there to suggest how the data should be written to a file ๐Ÿ“ byte (b) is either ASCII b <62>, for binary, or ASCII t <74>, for text. byte (b) may also take on the value ASCII 1, which means a machine-local conversion. PGP doesn't define how this gets converted across platforms, so that one's kinda a mystery ๐Ÿ™ˆ

field (c) suggests a filename ๐ŸŽ€ field (d) should be the time at which the file was last modified, or the time at which the data packet was created, or 0.

ngl, this part is lowkey genius โœจ only field (e) gets fed into a message-digest function when forming a signature. leaving out the other fields means detached signatures come out exactly the same as attached signatures prefixed to the message ๐Ÿฆ‹ detached signatures get calculated on a separate file that has none of the literal data packet header fields.

6.2. Signature packet โœ๏ธ

Purpose. signatures are attached to data in a way that only one entity, called the "writer," can create the signature ๐Ÿ’… the writer must first create a "public key" K and distribute it. the writer keeps certain private data related to K. only someone cooperating with the writer can sign data using K, enveloping the data in a signature packet (also known as a private-key-encrypted packet) ๐Ÿ’Œ anyone can look through the glass in the envelope and verify that the signature was attached to the data using K. and if the data gets altered in any way, the verification will fail ๐Ÿšจ

signatures have different meanings, like "I wrote this document" or "I received this document" ๐Ÿ“ that's why a signature packet includes a "classification" which expresses its meaning ๐Ÿท๏ธ

Definition. a signature packet, version 2 or 3, is the concatenation of these fields:

  • (a) packet structure field (2, 3, or 5 bytes);
  • (b) version number = 2 or 3 (1 byte);
  • (c) length of following material included in MD calculation (1 byte, always the value 5);
  • (d1) signature classification (1 byte);
  • (d2) signature time stamp (4 bytes);
  • (e) key ID for key used for signing (8 bytes);
  • (f) public-key-cryptosystem (PKC) type (1 byte);
  • (g) message digest algorithm type (1 byte);
  • (h) first two bytes of the MD output, used as a checksum (2 bytes);
  • (i) a byte string of encrypted data holding the RSA-signed digest.

the message digest is taken of the bytes of the file, followed by the bytes of field (d) ๐Ÿง it was originally intended that the length (c) could vary, but now it seems it will always remain a constant value of 5, and that is the only value that will be accepted. so only fields (d1) and (d2) get hashed into the signature along with the main message ๐Ÿ’œ

the message digest algorithm is specified by the message digest (MD) number of field (g). the following MD numbers are currently defined:

1 - MD5 (output length 16)
255 - experimental

more MD numbers may be defined in the future. an implementation need not support every MD number. the implementor must document the MD numbers understood by an implementation ๐Ÿ“š

a message digest algorithm reads a byte string of any length, and writes a byte string of some fixed length, as indicated in the table above โœจ

the input to the message digest algorithm is the concatenation of some "primary input" and some "appended input" ๐Ÿซง

the appended input is specified by field (c), which gives a number of bytes to be taken from the following fields: (d1), (d2), and so on. the current implementation uses the value 5 for this number, for fields (d1) and (d2). any field not included in the appended input is not "signed" by field (i) ๐Ÿ™…โ€โ™€๏ธ

the primary input is determined by the signature classification byte (d1). byte (d1) is one of the following hex numbers, with these meanings ๐Ÿ‘‘

<00> - document signature, binary image ("I wrote this document")
<01> - document signature, canonical text ("I wrote this document")
<10> - public key packet and user ID packet, generic certification
     ("I think this key was created by this user, but I won't say
     how sure I am")
<11> - public key packet and user ID packet, persona certification
     ("This key was created by someone who has told me that he is
     this user") (#)
<12> - public key packet and user ID packet, casual certification
     ("This key was created by someone who I believe, after casual
     verification, to be this user")  (#)
<13> - public key packet and user ID packet, positive certification
     ("This key was created by someone who I believe, after
     heavy-duty identification such as picture ID, to be this
     user")  (#)
<20> - public key packet, key compromise ("This is my key, and I
     have revoked it")

<30> - public key packet and user ID packet, revocation ("I retract
     all my previous statements that this key is related to this
     user")  (*)
<40> - time stamping ("I saw this document") (*)

more classification numbers may be defined in the future to handle other meanings of signatures, but only the above numbers may be used with version 2 or version 3 of a signature packet ๐Ÿšซ also, PGP 2.6.2 hasn't implemented the packets marked with an asterisk (*), and the packets marked with a hash (#) aren't output by PGP 2.6.2 ๐Ÿ™ˆ

signature packets are used in two different contexts ๐ŸŒธ one (signature type <00> or <01>) is of text (either the contents of a literal packet or a separate file). types <10> through <1F> only appear in key files, after the keys and user IDs that they sign. type <20> appears in key files, after the keys that it signs, and type <30> also appears after a key/userid combination. type <40> is intended to be a signature of a signature, like a notary seal on a signed document ๐Ÿ”

the output of the message digest algorithm is a message digest, or hash code ๐Ÿง  field (i) contains the ciphertext produced by encrypting the message digest with the signer's private key. field (h) contains the first two bytes of the unencrypted message digest. this lets the recipient check whether the correct public key was used to decrypt the message digest for authentication, by comparing this plaintext copy of the first two bytes with the first two bytes of the decrypted digest ๐Ÿ•ต๏ธโ€โ™€๏ธ these two bytes also serve as a 16-bit frame check sequence for the message โœจ

the message digest is signed by encrypting it using the writer's private key. field (e) is the ID of the corresponding public key.

the public-key-encryption algorithm is specified by the public-key cryptosystem (PKC) number of field (f). the following PKC numbers are currently defined:

1 - RSA
255 - experimental

more PKC numbers may be defined in the future. an implementation need not support every PKC number. the implementor must document the PKC numbers understood by an implementation ๐Ÿ“–

a PKC number identifies both a public-key encryption method and a signature method. both of these methods are fully defined as part of the definition of the PKC number ๐Ÿ’ซ some cryptosystems are usable only for encryption, or only for signatures. if any such PKC numbers are defined in the future, they will be marked appropriately ๐Ÿท๏ธ

6.2.3. RSA signatures ๐Ÿฆ‹

an RSA-signed byte string is a multiprecision field formed by taking the message digest, filling in an ASN structure, and then encrypting the whole byte string with the RSA key of the signer ๐Ÿ”

PGP versions 2.3 and later encode the MD into a PKCS-format signature string, which has this format ๐ŸŽ€

      MSB               .   .   .                    LSB
      0   1   <FF>(n bytes)   0   ASN(18 bytes)   MD(16 bytes)

see RFC1423 for an explanation of the meaning of the ASN string ๐Ÿ“š it is the following 18 byte long hex value: <30 20 30 0C 06 08 2A 86 48 86 F7 0D 02 05 05 00 04 10>

enough bytes of <FF> padding get added to make the length of this whole string equal to the number of bytes in the modulus ๐Ÿง

6.2.4. Miscellaneous fields ๐Ÿ’–

the timestamp field (d2) is kinda like the date box next to a signature box on a form ๐Ÿ“… it represents a time that's typically close to the moment the signature packet was created. however, this is not a requirement. users may choose to date their signatures however they like, just like they do with handwritten signatures โœ๏ธ

if an application needs trusted timestamps on signatures, a detached signature certificate with an untrusted timestamp may be submitted to a trusted timestamp notary service ๐Ÿ•ฐ๏ธ the notary signs the signature packet with another signature packet, creating a signature of a signature. the notary's signature's timestamp could then be used as the trusted "legal" time of the original signature ๐Ÿ‘‘ it's signatures all the way down ๐ŸŒˆ

6.3 Compressed data packets โœจ

Purpose. Okay so a compressed data packet is basically an envelope that squeezes its contents into a small space, and it does it safely ๐Ÿ“ฆ๐Ÿ’–

Definition. A compressed data packet is the concatenation of:

  • (a) a packet structure field;
  • (b) a byte, giving a compression type;
  • (c) a byte string of compressed data.

Byte string (c) is a packet which may be decompressed using the algorithm identified in byte (b). Typically, the data that are compressed consist of a literal data packet or a signature packet concatenated to a literal data packet. ๐ŸŽ€

A compression type picks the compression algorithm for use in compressed data packets. These compression numbers are currently defined ๐Ÿ‘‡

1 - ZIP
255 - experimental

More compression numbers may be defined in the future. An implementation need not support every MD number. The implementor must document the compression numbers understood by an implementation. Document your numbers, bestie, it's the rule ๐Ÿ“


6.4 Conventional-key-encrypted data packets ๐Ÿ”ฅ

Purpose. A conventional-key-encrypted data packet is formed by encrypting a block of data with a conventional encryption algorithm using a one-time session key. Typically, the block being encrypted is a compressed data packet. It's giving secret, no cap ๐Ÿคซ

Definition. A conventional-key-encrypted data packet is the concatenation of:

  • (a) a packet structure field;
  • (b) a byte string of encrypted data.

Okay, the plaintext (or compressed plaintext) that gets encrypted to form field (b) is first prepended with 64 bits of random data plus 16 "key check" bits. The random prefix starts off the cipher feedback chaining process with 64 bits of random material, which is the same job an initialization vector (IV) does for a cipher-block-chaining encryption scheme. The key check prefix is equal to the last 16 bits of the random prefix. ๐Ÿง 

During decryption, a comparison is made to see if the 7th and 8th byte of the decrypted material match the 9th and 10th bytes. If so, then the conventional session key used for decryption is assumed to be correct. Matching bytes = vibes confirmed โœ…


6.4.1 Conventional-encryption type byte ๐Ÿฆ‹

Purpose. The conventional-encryption type byte tells you which conventional encryption algorithm is in use. The algorithm type byte also defines how long the conventional encryption key is, based on the algorithm in use. ๐Ÿ—๏ธ

Definition. A conventional-encryption type byte is a single byte which defines the algorithm in use. The algorithm in use may need further definition, such as key-length. It is up to the implementor to document the supported key-length in such a situation. Here's the list:

1 - IDEA (16-byte key)
255 - experimental

6.5 Public-key-encrypted packets ๐Ÿ’œ

Purpose. The public-key-encrypted packet is the format for the session key component of a message. Its whole job is to carry the one-time session key used to encrypt the message over to the recipient in a secure way. It does this by encrypting the session key with the recipient's public key, so that only the recipient can recover the session key. Main character energy ๐Ÿ‘‘

Definition. A public-key-encrypted packet, version 2 or 3, is the concatenation of:

  • (a) a packet structure field;
  • (b) a byte, giving the version number, 2 or 3;
  • (c) a number ID field, giving the ID of a key;
  • (d) a byte, giving a PKC number;
  • (e) a byte string of encrypted data (DEK).

Byte string (e) represents the value of the session key, encrypted using the reader's public key K, under the cryptosystem identified in byte (d).

The value of field (c) is the ID of K.

Heads up: the packet does not actually identify K! Two keys can have the same ID, by chance or by malice ๐Ÿ™ˆ Usually it's super obvious from context which key K got used. But sometimes it's not, and that's when field (c) saves the day.

If, for example, a reader has created several keys and receives a message, then they should attempt to decrypt the message only with the key whose ID matches the value of field (c). If they've accidentally generated two keys with the same ID, then they must attempt to decrypt the message with both keys, but this case is highly unlikely to happen by chance. ๐ŸŽฒ


6.5.1 RSA-encrypted data encryption key (DEK) ๐ŸŒˆ

The Data Encryption Key (DEK) is a multiprecision field which stores an RSA encrypted byte string. The byte string is a PKCS encoding of the secret key used to encrypt the message, with random padding for each Public-Key encrypted packet. โœจ

PGP version 2.3 and later encode the DEK into an MPI using the following format:

     MSB                       .   .   .                       LSB
      0   2   RND(n bytes)   0  ALG(1 byte)  DEK(k bytes)  CSUM(2 bytes)

ALG refers to the algorithm byte for the secret key algorithm used to encrypt the data packet. The DEK is the actual Data Encryption Key, and its size depends on the encryption algorithm defined by ALG. For the IDEA encryption algorithm, type byte 1, the DEK is 16 bytes long.

CSUM is a 16-bit checksum of the DEK, used to determine that the correct Private key was used to decrypt this packet. The checksum is computed by the 16-bit sum of the bytes in the DEK. ๐Ÿงฎ

RND is random padding to expand the byte to fill the size of the RSA Public Key that is used to encrypt the whole byte. ๐ŸŽ€


6.6 Public Key Packet ๐Ÿงš

Purpose. A public key packet defines an RSA public key. Simple, iconic ๐Ÿ’…

Definition. A public key packet is the concatenation of:

  • (a) packet structure field (2 or 3 bytes);
  • (b) version number = 2 or 3 (1 byte);;
  • (c) time stamp of key creation (4 bytes);
  • (d) validity period in days (0 means forever) (2 bytes);
  • (e) public-key-cryptosystem (PKC) type (1 byte);
  • (f) MPI of RSA public modulus n;
  • (g) MPI of RSA public encryption exponent e.

The validity period is always set to 0. ๐ŸŒธ


6.7 User ID Packet ๐Ÿ’–

Purpose. A user ID packet identifies a user and is associated with a public or private key. It's the "this is me" card ๐Ÿชช

Definition. A user ID packet is the concatenation of:

  • (a) packet structure field (2 bytes);
  • (b) User ID string.

The User ID string may be any string of printable ASCII characters. However, since the whole point of this packet is to uniquely identify an individual, the usual practice is for the User ID string to consist of the user's name followed by an e-mail address for that user, with the e-mail address enclosed in angle brackets. Name + email in angle brackets, periodt ๐Ÿ’…


7. Transferable Public Keys ๐Ÿฆ‹

Public keys may be transferred between PGP users. The essential elements of a transferable public key are:

  • (a) One public key packet;
  • (b) One or more user ID packets;
  • (c) Zero or more signature packets

The public key packet occurs first. Each of the following user ID packets provides the identity of the owner of this public key. If there are multiple user ID packets, this corresponds to multiple means of identifying the same unique individual user. For example, a user may enjoy the use of more than one e-mail address, and construct a user ID packet for each one. Iconic multitasking ๐Ÿ’โ€โ™€๏ธ

Immediately following each user ID packet, there are zero or more signature packets. Each signature packet is calculated on the immediately preceding user ID packet and the initial public key packet. The signature serves to certify the corresponding public key and user ID. In effect, the signer is testifying to their belief that this public key belongs to the user identified by this user ID. Receipts, bestie ๐Ÿงพโœจ


8. Acknowledgments ๐Ÿซถ

Philip Zimmermann is the creator of PGP 1.0, which is the precursor of PGP 2.x. Major parts of later versions of PGP have been implemented by an international collaborative effort involving a large number of contributors, under the design guidance of Philip Zimmermann. Literal legends ๐ŸŒŸ


9. Security Considerations ๐Ÿ’€

Security issues are discussed throughout this memo. Read this one carefully, bestie, it's SERIOUS business ๐Ÿšจ

10. Authors' Addresses ๐Ÿ’Œ

Here's who to tag if you have questions ๐Ÿ‘‡

Derek Atkins
12 Rindge Ave. #1R
Cambridge, MA

Phone: +1 617 868-4469
EMail: warlord@MIT.EDU


William Stallings
Comp-Comm Consulting
P. O. Box 2405
Brewster, MA 02631

EMail: stallings@ACM.org


Philip Zimmermann
Boulder Software Engineering
3021 Eleventh Street
Boulder, Colorado 80304  USA

Phone: +1-303-541-0140
EMail: prz@acm.org
๐Ÿ“ฆ where this page comes from