Skip to content

PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm — crash on permission-only-encrypted PDFs (Flash preview) #426

Description

@ysasiwat

Summary

page_index_flash() crashes with PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm on any AES-encrypted PDF, including PDFs that only use encryption for permission flags (copy/print restrictions) with an empty user password — i.e. PDFs that open and read fine in any normal viewer. requirements.txt on this branch pins PyPDF2==3.0.1 but does not include pycryptodome, which PyPDF2 needs as an optional dependency to decrypt AES-protected content streams.

Environment

  • Branch/commit: feat/pageindex-flash @ c7243700c7aa37bad386a5878b1badc269fcc7a2
  • Python: 3.12.13 (Windows)
  • PyPDF2==3.0.1, pypdfium2==4.30.0 (as pinned in requirements.txt)
  • Invocation: run_pageindex.py --pdf_path <file> --flash

Repro

Run Flash against any text-layer PDF that uses AES encryption for permissions only (a common pattern for publicly distributed standards/reference documents — no password prompt needed to open or read it in a normal PDF viewer):

python run_pageindex.py --pdf_path <aes-encrypted.pdf> --flash

Traceback

Traceback (most recent call last):
  File "run_pageindex.py", line 60, in <module>
    toc_with_page_number = page_index_flash(args.pdf_path)
  File "pageindex/flash/api.py", line 73, in page_index_flash
    return extract_toc(_validate_pdf(pdf))
  File "pageindex/flash/main.py", line 131, in extract_toc
    parsed, page_meta = parse_charlevel_meta(doc_handle)
  File "pageindex/flash/parser_pdfium_charlevel/pipeline.py", line 117, in parse_charlevel_meta
    if pdf_doc is not None and page_idx < pdf_doc.page_count:
  File "pageindex/flash/parser_pdfium_charlevel/pdf_objects.py", line 125, in page_count
    return len(self._reader.pages)
  File ".venv/Lib/site-packages/PyPDF2/_page.py", line 2063, in __len__
    return self.length_function()
  File ".venv/Lib/site-packages/PyPDF2/_reader.py", line 445, in _get_num_pages
    return self.trailer[TK.ROOT]["/Pages"]["/Count"]
  File ".venv/Lib/site-packages/PyPDF2/generic/_data_structures.py", line 266, in __getitem__
    return dict.__getitem__(self, key).get_object()
  File ".venv/Lib/site-packages/PyPDF2/generic/_base.py", line 259, in get_object
    obj = self.pdf.get_object(self)
  File ".venv/Lib/site-packages/PyPDF2/_reader.py", line 1205, in get_object
    retval = self._get_object_from_stream(indirect_reference)
  File ".venv/Lib/site-packages/PyPDF2/_reader.py", line 1136, in _get_object_from_stream
    obj_stm: EncodedStreamObject = IndirectObject(stmnum, 0, self).get_object()
  File ".venv/Lib/site-packages/PyPDF2/generic/_base.py", line 259, in get_object
    obj = self.pdf.get_object(self)
  File ".venv/Lib/site-packages/PyPDF2/_reader.py", line 1269, in get_object
    retval = self._encryption.decrypt_object(
  File ".venv/Lib/site-packages/PyPDF2/_encryption.py", line 761, in decrypt_object
    return cf.decrypt_object(obj)
  File ".venv/Lib/site-packages/PyPDF2/_encryption.py", line 185, in decrypt_object
    obj._data = self.stmCrypt.decrypt(obj._data)
  File ".venv/Lib/site-packages/PyPDF2/_encryption.py", line 147, in decrypt
    raise DependencyError("PyCryptodome is required for AES algorithm")
PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm

Suggested fix

Either:

  1. Add pycryptodome to requirements.txt so AES-encrypted PDFs decode correctly (installing it locally against this same pinned checkout resolves the crash), or
  2. Catch PyPDF2.errors.DependencyError in the Flash path (parser_pdfium_charlevel/pdf_objects.py / pipeline.py) and surface it as a handled "unsupported PDF" result — same as the existing handling for scanned/encrypted PDFs mentioned in the README — instead of an unhandled exception.

Option 1 is preferable where possible: many permission-only-encrypted PDFs have no real password barrier and are otherwise perfectly parseable once the dependency is present.

Context

Found via a downstream integration (a pinned, local-only install of this Flash preview branch) hitting this reproducibly on a real corpus PDF. Happy to share more detail if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions