From PDF 1.1 a file can be encrypted. The structure stays readable: the header, the objects’ numbers and dictionaries, the cross-reference table and the trailer are all as in any file. What is encrypted is the content of every string and every stream, each with its own key made from one file key. In PDF 1.1 to 1.4 the cipher is RC4, with a 40-bit key, or from PDF 1.4 a key of up to 128 bits. A security handler decides how the file key is found: from passwords with the standard handler, or from a certificate with a public-key handler.
The encryption dictionary
The trailer’s Encrypt entry holds it, and the trailer then must also
have an ID.
| Key | Since | Meaning |
|---|---|---|
Filter | 1.1 | Required: the security handler, Standard for passwords |
SubFilter | 1.3 | The format of the dictionary, so that another handler that knows it can open the file |
V | 1.1 | The algorithm: 0 not used; 1 RC4 with a 40-bit key; 2 (1.4) RC4 with a key of 40 to 128 bits; 3 (1.4) an unpublished algorithm, not for general use |
Length | 1.4 | For V 2 or 3: the key length in bits, a multiple of 8 from 40 to 128; default 40 |
The standard handler adds R, O, U and
P:
<< /Filter /Standard /V 2 /R 3 /Length 128 /P -3904
/O <… 32 bytes …> /U <… 32 bytes …> >>
How each object is encrypted
Every string and stream is encrypted with RC4 under a key made from the file key and the number of the indirect object it is in:
- Take the file key, n bytes (5 for V 1,
Length÷ 8 for V 2). - Append the low three bytes of the object number and the low two bytes of the generation number, low byte first.
- Take the MD5 digest of those n + 5 bytes.
- The object’s key is the first n + 5 bytes of the digest, at most 16.
RC4 encrypts and decrypts the same way, and the data keeps its length. A stream is encrypted after its filters were applied, so a reader decrypts first and then undoes the filters. Strings inside a dictionary or array take the key of the indirect object that holds them.
Not encrypted: the strings of the encryption dictionary itself, the trailer’s
ID, and everything that is not a string or stream: numbers, names,
dictionary keys, the table.
The standard security handler
The standard handler works with two passwords. The user password opens the file; if it is empty, as it often is, anyone can open the file and the encryption only carries the permissions. The owner password opens it with every permission. Both are checked against the dictionary’s strings:
| Key | Meaning |
|---|---|
R | Required: the revision. 2 for V 1 with only the first four permissions; 3 for V 2 or 3, or when any revision 3 permission is cleared |
O | Required: 32 bytes made from the owner and user passwords |
U | Required: 32 bytes made from the user password |
P | Required: the permissions, a 32-bit signed integer |
Passwords are bytes. Writers in these versions take them in PDFDocEncoding; they are cut or padded to 32 bytes with this fixed padding string:
28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08
2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A
Making the file key from a password
- Pad or cut the password to 32 bytes.
- Start an MD5 digest and feed it those 32 bytes.
- Feed it the 32 bytes of
O. - Feed it
Pas four bytes, low byte first. - Feed it the first string of the trailer’s
ID. - Finish the digest.
- Revision 3 only: 50 times, take the MD5 digest of the first n bytes of the previous digest.
- The file key is the first n bytes: 5 for revision 2,
Length÷ 8 for revision 3.
The U string and checking the user password
Revision 2: U is the padding string encrypted with RC4 under the file
key. Revision 3:
- Make the file key from the user password.
- Take the MD5 digest of the padding string followed by the first
IDstring: 16 bytes. - Encrypt it with RC4 under the file key.
- 19 more times, for i from 1 to 19, encrypt the result with RC4 under the file key with every byte XORed with i.
- The 16 bytes are the first half of
U; the other 16 are anything.
To check a user password, compute U from it and compare: all 32 bytes
for revision 2, the first 16 for revision 3. If they match, the key made in the
first step opens the file. A reader always tries the empty password first.
The O string and checking the owner password
To make O:
- Pad the owner password, or the user password if there is no owner password, to 32 bytes.
- Take its MD5 digest. Revision 3 only: 50 more times, take the MD5 digest of the digest.
- The RC4 key is the first n bytes (5 for revision 2).
- Pad the user password and encrypt it with RC4 under that key.
- Revision 3 only: 19 more times, for i from 1 to 19, encrypt the result under the key with every byte XORed with i.
- The 32 bytes are
O.
To check an owner password, make the RC4 key from it as in the first three steps
and decrypt O: once for revision 2; for revision 3, twenty times, with
the key XORed with 19, 18 and so on down to 0. The result is the user password,
padded. Check that as a user password; if it is right, the owner password is too.
So the owner password only unlocks the user password. A reader that knows the user password has the file key and can decrypt everything; obeying the permissions is up to the reader.
Permissions
P is a set of bits, bit 1 the lowest. Bits 1 and 2 must be 0, bits 7
and 8 must be 1, and in revision 3 bits 13 to 32 must be 1, so the value is
negative. A set bit allows the operation when the file is opened with the user
password.
| Bit | Revision | Allows |
|---|---|---|
| 3 | 2, 3 | Printing; in revision 3, at the quality bit 12 allows |
| 4 | 2, 3 | Changing the document in ways other than bits 6, 9 and 11 |
| 5 | 2, 3 | Copying or extracting text and graphics; in revision 2 also for accessibility |
| 6 | 2, 3 | Adding and changing annotations, and filling in fields; with bit 4, creating fields |
| 9 | 3 | Filling in existing form fields, signature fields included, even if bit 6 is clear |
| 10 | 3 | Extracting text and graphics for accessibility |
| 11 | 3 | Assembling: inserting, rotating and deleting pages, making bookmarks and thumbnails |
| 12 | 3 | Printing at full quality; if clear while bit 3 is set, only a degraded copy |
P -4 (FF FF FF FC) allows everything. P -3904
(FF FF F0 C0) allows nothing beyond viewing: only the bits that must be
1 are set.
Public-key handlers
From PDF 1.3 a file can instead be encrypted for named recipients, each with a
certificate. The encryption dictionary has a handler such as
Adobe.PubSec as Filter, and a SubFilter of
adbe.pkcs7.s3 (PDF 1.3, revision 2 permissions) or
adbe.pkcs7.s4 (PDF 1.4, revision 3 permissions). Its
Recipients array holds one PKCS#7 enveloped-data object for each group
of recipients, encrypted to their public keys. Each envelope holds a 20-byte seed
and the permissions for those recipients.
A recipient with the private key opens an envelope and takes the seed. The file
key is the first n bytes of the SHA-1 digest of the seed followed by the
bytes of every Recipients entry, in order. Strings and streams are then
encrypted with RC4 exactly as with the standard handler.
How strong it is
Forty-bit RC4 keys can be found by trying them all, in hours on today’s computers, without any password. RC4 itself is broken for many uses, and the user password is checked with a few MD5 and RC4 rounds, so short passwords are easy to guess. The permissions are not enforced by the encryption at all: they are flags that a reader is asked to obey. These versions’ encryption is best seen as keeping honest readers to the author’s wishes, not as protecting secrets.