Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypting - Image color index unchanged #2188

Open
pilotandy opened this issue Sep 12, 2023 · 5 comments
Open

Encrypting - Image color index unchanged #2188

pilotandy opened this issue Sep 12, 2023 · 5 comments
Labels
Has MCVE A minimal, complete and verifiable example helps a lot to debug / understand feature requests workflow-encryption From a users perspective, encryption is the affected feature/workflow

Comments

@pilotandy
Copy link
Contributor

When encrypting a PDF with CMYK Indexed color, the colors render incorrectly on the encrypted PDF.
It appears the stream gets encrypted, but the color palette does not, as it is in the dictionary, not the stream of the object.

14 0 obj
<<
/Type/XObject
/Subtype/Image
/Width 576
/Height 229
/BitsPerComponent 8
/ColorSpace [/Indexed/DeviceCMYK 18 <0000001200000011000000100000000f0000000e0000000d0000000c0000000b0000000a00000009000000080000000700000006000000050000000400000003000000020000000100000000>]
/Filter/FlateDecode
/Length 2036
>>
stream
....
endstream
endobj

The output shows the same CMYK values as the input

32 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 576
/Height 229
/BitsPerComponent 8
/ColorSpace [ /Indexed /DeviceCMYK 18 <0000001200000011000000100000000f0000000e0000000d0000000c0000000b0000000a00000009000000080000000700000006000000050000000400000003000000020000000100000000> ]
/Filter /FlateDecode
/Length 2036
>>
stream
...
endstream
endobj

In _encryption.py, starting around line 75, we encrypt the stream, but not the dictionary

elif isinstance(obj, StreamObject):
    obj2 = StreamObject()
    obj2.update(obj)
    obj2.set_data(self.stmCrypt.encrypt(b_(obj._data)))
    obj = obj2

Adding the items of the dictionary, and evaluating them as well

elif isinstance(obj, StreamObject):
    obj2 = StreamObject()
    obj2.update(obj)
    obj2.set_data(self.stmCrypt.encrypt(b_(obj._data)))
    # We're encrypting the stream, consider the dictionary too.
    for key, value in obj.items():
        obj2[key] = self.encrypt_object(value)
    obj = obj2

Now, the CMYK values are encrypted too.

32 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 576
/Height 229
/BitsPerComponent 8
/ColorSpace [ /Indexed /DeviceCMYK 18 <64cda2cefbf39121492b5dfbe74cb864ec4c6101b2675d53c47ae2b5e7591ea3ba6bd2b6bcb1f13eff191f47b9495db796077831f49ac3771b0d0c23eb61418a4df5ddc4945cb16b3b217c86> ]
/Filter /FlateDecode
/Length 2036
>>
stream
....
endstream
endobj

Adobe Acrobat will then decrypt the CMYK color values correctly.

@stefan6419846
Copy link
Collaborator

As you apparently managed to identify the root cause and found a fix: Are you willing to submit a PR including a corresponding test ensuring that this indeed is working correctly with the fix employed?

@pubpub-zz
Copy link
Collaborator

@exiledkingcc
Can you give your opinion?

@pilotandy
Copy link
Contributor Author

I’m sorry, I’ve been busy. I can’t use the PDF I found the issue on (it’s not mine), but I can mock something up and create some PRs. It just may take a while.

@exiledkingcc
Copy link
Contributor

a good fix!

@MartinThoma MartinThoma added workflow-encryption From a users perspective, encryption is the affected feature/workflow Has MCVE A minimal, complete and verifiable example helps a lot to debug / understand feature requests labels Sep 24, 2023
@pilotandy
Copy link
Contributor Author

New PR #2228
still broken though :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Has MCVE A minimal, complete and verifiable example helps a lot to debug / understand feature requests workflow-encryption From a users perspective, encryption is the affected feature/workflow
Projects
None yet
Development

No branches or pull requests

5 participants