Repository navigation
proposal: give pypdf an AES backend so AES-encrypted PDFs can be read #209
Description
Problem
pypdf decrypts AES only through an optional crypto backend: cryptography, or pycryptodome under the Crypto namespace. The API depends on pycryptodomex, whose namespace is Cryptodome, and pypdf does not look for that one. In the locked API environment pypdf therefore runs on its fallback, which handles RC4 only:
$ uv run --frozen --project services/api python -c "import pypdf._crypt_providers as c; print(c.crypt_provider)"
('local_crypt_fallback', '0.0.0')Acrobat has offered AES for permission passwords since version 7 (AES-128) and X (AES-256), so a PDF restricted with a current tool is likely to be an AES file. #208 accepts PDFs that carry only an owner password (#115), but it can do that only for RC4 files. An AES file with an empty user password is still refused as encrypted, because its content cannot be decrypted here.
Measured with synthetic files from pypdf 6.19.0 (the locked version) and the code in #208:
| file | locked API environment | same environment plus cryptography |
|---|---|---|
| RC4-40 / RC4-128, owner password only | accepted, text parsed | accepted, text parsed |
| AES-128, owner password only | refused: encrypted | accepted, text parsed |
| AES-256, owner password only | refused: encrypted | accepted, text parsed |
| any of these with a user password | refused: encrypted | refused: encrypted |
Proposed behavior
Give pypdf a backend by depending on pypdf[crypto] in services/api, the extra pypdf documents for this, which pulls in cryptography. The validation from #208 needs no change for the right-hand column. A test can then generate AES-128 and AES-256 owner-only PDFs with PdfWriter.encrypt(user_password="", owner_password=..., algorithm=...), which also needs the backend, and assert that they upload with text while user-password files stay refused.
Alternatives considered
- Add
pycryptodomenext topycryptodomex. pypdf would find it, but the API would then carry the same library under two namespaces. - Keep refusing AES files and say so in the upload error and the self-hosting docs. This keeps the dependency set, and most restricted publisher PDFs stay refused.
Compatibility and research-method implications
No research-method change. More uploads are accepted: AES files with only an owner password. Every file that needs a password to open is still refused, and no password is ever accepted, stored or logged. The API image gains one compiled dependency.
Dependencies, network, and data terms
New runtime dependency cryptography (PyCA, Apache-2.0 OR BSD-3-Clause, wheels for the supported platforms), through pypdf[crypto]. No network calls and no data egress. This issue comes before any PR because CONTRIBUTING asks for one before a new dependency.
Submission checks
- This proposal fits the community source tree and does not require production secrets, customer data, payment/subscription code, or hosted administration.
- I searched existing issues and discussions for the same proposal.
- I agree to follow the Code of Conduct.
Activity