Expand description
§pdfrum-crypt
The standard security handler (ISO 32000-1 §7.6), revisions 2 through 6: an
/Encrypt dictionary plus a password produce a SecurityHandler, and every
string and stream in the file decrypts through it, keyed by the indirect
object it belongs to.
use pdfrum_crypt::{CryptClass, SecurityHandler};
use pdfrum_object::ObjRef;
let handler = SecurityHandler::Identity;
assert_eq!(handler.decrypt(ObjRef::new(1, 0), CryptClass::Stream, b"raw"), b"raw");The object reference is not optional context — it is part of the key.
Revisions 2 to 4 derive an RC4 or AES-128 key by an MD5 ladder over the padded
password and the object’s number and generation, so the same bytes at a
different object number decrypt to something else. Revisions 5 and 6 verify a
SHA-2 hash and unwrap a 32-byte AES-256 key the file stores directly, and only
there is the key object-independent. CryptClass distinguishes strings from
streams because /StmF and /StrF can name different crypt filters.
The AES-CBC initialisation vector is an argument rather than something this
crate mints, because a decrypting caller reads it off the ciphertext and only
an encrypting one has to produce it. pdfrum-edit draws file keys and
vectors from the operating system for every encrypted save; a fixed seed
still pins /ID bytes, not the secrets.
Two things are deliberately out of scope. Building a new /Encrypt
dictionary is revision 6 only (standard_r6), because /O, /U, /OE,
/UE and /Perms are written by whoever chose the passwords. And graph
walks stay in the caller — whether a signature’s /Contents is exempt, or
/EncryptMetadata applies, is a question about the document, not about a
cipher.
Public-key handlers (Adobe.PubSec) are not implemented.
Part of pdfrum. #![forbid(unsafe_code)].
MIT OR Apache-2.0
Structs§
- Encrypt
Params - The
/Encryptdictionary as a record of what the file said. - Iv
- One AES initialisation vector, supplied by the caller of
crate::SecurityHandler::encrypt. - KeyMaterial
- The secret bytes behind one encrypted file: the AES-256 file key, the
four revision-6 salts (ISO 32000-2 §7.6.4.4.7, algorithms 8 and 9), and
four random bytes for
/Perms(Algorithm 10). - Permissions
- What a document’s security handler permits.
- Small
Key - A file encryption key of at most 32 bytes.
Enums§
- Cipher
- The cipher a document’s crypt filter resolves to.
- Crypt
Class - Which crypt filter class a payload belongs to.
- Error
- What went wrong building a security handler.
- Password
Encoding - Which spelling of a password unlocked a document.
- Security
Handler - A document’s decryption state: which cipher, which key, and what the password unlocked.
Constants§
- ENTROPY_
LEN - The bytes of a new file’s secrets: the 32-byte file key, then the
user validation salt, user key salt, owner validation salt and owner key
salt, 8 bytes each, then four random bytes for
/Perms(ISO 32000-2 Algorithm 10). - PAD
- The 32-byte padding string every revision 2 to 4 password is padded with (ISO 32000 §7.6.3.3, “Algorithm 2” step a).
Functions§
- is_
signature_ dict - Whether
dictis a signature dictionary, whose/Contentsmust stay undecrypted. - md5
- MD5 of one buffer (RFC 1321).
- parse_
encrypt_ dict - Read an
/Encryptdictionary into anEncryptParams. - rc4
- Crypt
dataunderkey, returning a fresh buffer. - sha1
- SHA-1 of one buffer (FIPS 180-2).
- standard_
r6 - The
/Encryptdictionary and the handler that enciphers under it, for a document protected byuser(opens with reading rights) andowner(opens with every right). An empty user password means anyone can open the file; an empty owner password is replaced by the user password, as Acrobat does, so there is always a way to unlock it.