julianhille / MuhammaraJS

Muhammara a node module with c/cpp bindings to modify PDF with js for node or electron (based/replacement on/of galkhana/hummusjs)
Other
228 stars 46 forks source link

Clarify AES-256 encryption support #380

Open thmclellan opened 6 months ago

thmclellan commented 6 months ago

Does Muhammara support AES-256 encryption? That seems to be recommended as part of PDF 2.0 standard, and I see references to AES-256 here, but it doesn't seem to work with a test file: https://github.com/julianhille/MuhammaraJS/blob/3392b8ffb346079c57196378b2ced1502d09bcfa/src/deps/LibAesgm/aescpp.h#L45

For example, an AES-256 encrypted file opens fine in Mac Preview, but generates an error when you try to open it with a user password in the muhammara 4.x.

I wondered if maybe there's existing support for AES-256 in CBC (Cipher Block Chaining) mode or CFB (Cipher Feedback) mode but not both, if it's an environment dependency issue (running on Ubuntu / Heroku), or some other known issue related to some of these encrypted files. I can spend some time on this if you could point me in the right direction. Thanks

thmclellan commented 6 months ago

I did a bit more digging and should have realized that earlier AES-256 reference was just to do a crypto dependency. Looking at PDFWriter's DecryptionHelper.cpp L127, you can see that only encryption algorithms of V1, V2, and V4 are supported: https://github.com/julianhille/MuhammaraJS/blob/3392b8ffb346079c57196378b2ced1502d09bcfa/src/deps/PDFWriter/DecryptionHelper.cpp#L127

QPdf has a nice summary of the encryption algorithm parameters V and R at https://qpdf.readthedocs.io/en/stable/encryption.html#pdf-encryption-details.

Muhammara/PDFWriter seems to support RC4 (legacy encryption 40 to 128 bits) and AES-128 encryption but not AES-256.

The example file I sent earlier had V = 5 and R = 6 but was actually PDF 1.7 (removed). I found a better set of test files on PDF Association site at https://pdfa.org/wp-content/uploads/2023/01/crypto-extensions-samples.zip with background at https://pdfa.org/pdf-2-0-modernizes-cryptographic-support/. It seems like AES-256 CBC support is the most popular encryption method with the PDF 2.0 spec and AES-256 GCM was added to the spec in June 2023 (https://pdfa.org/pdf-20-adds-aes-gcm-support/). AES-256 GCM doesn't seem to be supported by Acrobat Reader or Mac Preview yet.

It sounds like there's some extra complexity around whether the userpassword and ownerpassword are the same or different, per the above QPDF page and the PDF Association's sample files.

Anyway, I'm realizing adding more encryption support might be a bigger effort and require more C++ skills, but in any case wanted to share what I'm seeing. Here attached are the PDF 2.0 AES 256 CBC file (both user and owner passwords are 'secret') and the AES 128 file (pass 123123, works fine in Muhammara).

aes-128-v4-r4-pass-123123.pdf aes-cbc-256-v5-r6-standard-pass-secret.pdf