Skip to content

pdf2john.py incorrectly defaults to 40-bit key length in V4/R4 PDF #6033

Description

@alex-barth

Hi,
I found a V4/R4 PDF where the encryption dictionary does not contain a top-level /Length, but the applicable crypt filter does:

qpdf output for the encryption object:

/V 4
/R 4
/CF <<
  /StdCF <<
    /AuthEvent /DocOpen
    /CFM /AESV2
    /Length 16
  >>
>>
/StmF /StdCF
/StrF /StdCF

There is no top-level /Length entry.

Running:

pdf2john.py sample.pdf

produces:

$pdf$4*4*40*-4*...

The 40 seems to come from:

self.length = self.encrypt_dict.get("/Length", 40)

However, for this V4/R4 PDF the applicable /StdCF crypt filter has:

/Length 16

which corresponds to a 128-bit encryption key.

For comparison, qpdf --show-encryption --password='...' sample.pdf reports:

R = 4
stream encryption method: AESv2
string encryption method: AESv2
file encryption method: AESv2

The resulting 40 in the $pdf$ hash causes john to interpret the PDF as having a 40-bit key, even though the actual encryption uses AES-128.
This then results in the hash not being able to be cracked.

Manually chaning the length to 128 instead of 40 fixes the issue and the password was correctly found by john.

PDF metadata:

Creator:     Aspose Pty Ltd.
Producer:    PDFsharp 6.2.0 (Original: Aspose.PDF for .NET 26.3.0)
PDF version: 1.7
Encryption:  AES (Revision 4 / V4)

The reference also states that /Length is optional:
https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf - section 3.5, page 117

(Optional; PDF 1.4; only if V is 2 or 3) The length of the encryption key, in bits. The value
must be a multiple of 8, in the range 40 to 128. Default value: 40.

Expected behavior

For V4/R4 PDFs using a crypt filter, pdf2john.py should determine the effective key length from the applicable crypt filter when /Length is not present at the top level, rather than unconditionally falling back to the 40-bit default.

KR Alex

Activity

  1. solardiz commented on Sep 2, 2026

    @solardiz
    Member

    Thanks. I labeled this a "bug", although I'm not entirely sure.

    Is this something you researched yourself and understand well, or did you use AI?

    Can you share a sample PDF (with no security sensitive content) that exposes the problem? We'd like this in our https://github.com/openwall/john-samples repo.

    Can you contribute your proposed fix via a pull request?

    I apologize in advance that we currently have a backlog of pending PRs, so we may not review/merge this quickly, but we intend to eventually process all of them.

  2. alex-barth commented on Sep 3, 2026

    @alex-barth
    Author

    I researched it a bit when I encountered it, but I'm not that deep into the PDF spec.

    I can't share the original sample PDF since it contains sensitive data, but I'll try to spin up a windows VM on the weekend to reproduce it with the same program.
    Same with the PR, but not sure yet if I have enough time this weekend.

    No worries :)

    PS: I'm also not sure yet if a similar issue can happen if the root /Length is missing on other V/R combinations or only on 4/4.

  3. alex-barth commented on Sep 8, 2026

    @alex-barth
    Author

    Found additional clues in the pdfsharp changelog:

    Optional /Length entry for encryption added always
    The PDF viewer of Edge fails to open some encrypted PDF files if the /Length entry is not present. GitHub #261
    We now always add the /Length entry even in cases where it is optional according to PDF specifications.

    Source: https://docs.pdfsharp.net/PDFsharp/History.html#whats-new-in-version-624
    And a comment on the mentioned github issue: empira/PDFsharp#261 (comment)

    I created the pdfs in the meantime also using pdfsharp 6.2.0

    sample-V4-R2-RC4-128.pdf
    sample-V4-R4-AES-128.pdf
    edit: also added the other pdfs and created a PR for the openwall/john-samples repo

    The owner password is: owner123
    The user password is: user123

    In my opinion pdf2john should still be able to handle these pdfs, since by the spec they are still valid.

  4. self-assigned this
    on Sep 30, 2026
  5. kholia commented on Sep 30, 2026

    @kholia
    Member

    Thanks - I was able to reproduce this problem easily via your sample PDF files.

    I have opened #6043 to fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions