PyPDF2 to pypdf copying over original document passwords using protected attributes of PDFWriter #2079
-
Hi, I'm working on migrating from pypdf2 to pypdf. MY scenario is as follows:
When I encrypt again, I want the original passwords to be copied over and then encrypted with the owner_password.
I'm having trouble doing this in pypdf. I'm able to fetch the reader properties. But don't know what to modify on the writer. Maybe writer._encryption? or writer._encrypt_entry? The writer's encrypt function implementation has changed from pypdf2 and new property names are being used. |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 2 replies
-
Basically as an owner, can I encrypt the writer again using the existing user_passwords? I don't know what they are but I want to keep them there. |
Beta Was this translation helpful? Give feedback.
-
@exiledkingcc |
Beta Was this translation helpful? Give feedback.
-
@mmalik1234 maybe you can try this, althoght i have not verified if it can work: reader.decrypt(owner_password)
# copy the PdfReader._encryption
# copy the "/Encrypt" entry
# do something else
# call writer encrypt first
writer.encrypt(owner_password)
# then replace PdfWriter._encryption with PdfReader._encryption
# also replace PdfWriter._encrypt_entry with copied "/Encrypt" entry
# then call write
writer.write(pdf_file) |
Beta Was this translation helpful? Give feedback.
-
@exiledkingcc Thank you so much for the answer. I tried it but it seems that the password is incorrect now? Maybe it saved an encrypted version? I get this error for the correct user and owner_password that I set: |
Beta Was this translation helpful? Give feedback.
-
I did the following test:
the result |
Beta Was this translation helpful? Give feedback.
-
@pubpub-zz Hey the scneario is a little different. After I encrypt with "test" and "owner", I want to do
|
Beta Was this translation helpful? Give feedback.
-
Here's a mockup scenario of my code. Don't look too deep into it for smal stuff since I wrote a very base-level one for the discussion. The main part is copying the original passwords:
|
Beta Was this translation helpful? Give feedback.
-
@mmalik1234 i have time to verify it today. my bad to ignore the ID and the reference changed in my last reply. i have figured out how to make it work. you can try this one: def test_reuse_encrypt():
curr_dir = Path(__file__).parent.resolve()
with open(curr_dir / "x.pdf", "rb") as ff:
pdf = ff.read()
reader = PdfReader(io.BytesIO(pdf))
reader.decrypt("ownerpass")
e_cls = reader._encryption
e_entry = reader.trailer["/Encrypt"]
# need keep ID, which is used to auth the passwords
e_id = reader.trailer["/ID"]
writer = PdfWriter()
for p in reader.pages:
writer.add_page(p)
# writer.encrypt("ownerpass")
writer._encryption = e_cls
writer._encrypt_entry = e_entry
# add object to make the reference correct
writer._add_object(e_entry)
writer._ID = e_id
writer.write("a.pdf") |
Beta Was this translation helpful? Give feedback.
@mmalik1234 i have time to verify it today. my bad to ignore the ID and the reference changed in my last reply. i have figured out how to make it work. you can try this one: