Skip to content

Commit

Permalink
ROB: Crop data of /U and /O in encryption dictionary to 48 bytes (#1317)
Browse files Browse the repository at this point in the history
The specification says:

To understand the algorithm below, it is necessary to treat the O and U strings in the Encrypt dictionary
as made up of three sections. The first 32 bytes are a hash value (explained below). The next 8 bytes are
called the Validation Salt. The final 8 bytes are called the Key Salt.

So /U and /O should be 48-bytes data, but for the PDF file which causes #1288 , /O 's length is 127-bytes. The redundant data are zeros.

Fixes #1288
  • Loading branch information
exiledkingcc authored Sep 3, 2022
1 parent 1252a49 commit a61ef5f
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions PyPDF2/_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,10 @@ def verify_owner_password(
should match the value in the P key.
"""
password = password[:127]
if AlgV5.calculate_hash(R, password, o_value[32:40], u_value) != o_value[:32]:
if AlgV5.calculate_hash(R, password, o_value[32:40], u_value[:48]) != o_value[:32]:
return b""
iv = bytes(0 for _ in range(16))
tmp_key = AlgV5.calculate_hash(R, password, o_value[40:], u_value)
tmp_key = AlgV5.calculate_hash(R, password, o_value[40:48], u_value[:48])
key = AES_CBC_decrypt(tmp_key, iv, oe_value)
return key

Expand All @@ -532,7 +532,7 @@ def verify_user_password(
if AlgV5.calculate_hash(R, password, u_value[32:40], b"") != u_value[:32]:
return b""
iv = bytes(0 for _ in range(16))
tmp_key = AlgV5.calculate_hash(R, password, u_value[40:], b"")
tmp_key = AlgV5.calculate_hash(R, password, u_value[40:48], b"")
return AES_CBC_decrypt(tmp_key, iv, ue_value)

@staticmethod
Expand Down

0 comments on commit a61ef5f

Please sign in to comment.