RFC 1991
PGP Message Exchange Formats
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 ofB. the implementor MUST document which values ofBare 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 ๐
6.2.1. Message-digest-related fields ๐
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 โจ
6.2.2. Public-key-related fields ๐๏ธ
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
- ietf: rfc1991 1996-08
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms