PyPDF 2 Decrypt Not Working
Solution 1
To Answer My Own Question: If you have ANY spaces in your file name, then PyPDF 2 decrypt function will ultimately fail despite returning a success code. Try to stick to underscores when naming your PDFs before you run them through PyPDF2.
For example,
Rather than "FDJKL492019 21490 ,LFS.pdf" do something like "FDJKL492019_21490_,LFS.pdf".
Solution 2
This error may come about due to 128-bit AES encryption on the pdf, see Query - is there a way to bypass security restrictions on a pdf?
One workaround is to decrypt all isEncrypted pdfs with "qpdf"
qpdf --password='' --decrypt input.pdf output.pdf
Even if your PDF does not appear password protected, it may still be encrypted with no password. The above snippet assumes this is the case.
Solution 3
The following code could solve this problem:
import os
from PyPDF2 import PdfReader
filename = "example.pdf"
reader = PdfReader(filename)
if reader.is_encrypted:
try:
reader.decrypt("")
print("File Decrypted (PyPDF2)")
except:
command = (
"cp "
+ filename
+ " temp.pdf; qpdf --password='' --decrypt temp.pdf "
+ filename
+ "; rm temp.pdf"
)
os.system(command)
print("File Decrypted (qpdf)")
reader = PdfReader(filename)
else:
print("File Not Encrypted")
Solution 4
Implement qpdf using python with pikepdf library.
import pikepdf
pdf = pikepdf.open('unextractable.pdf')
pdf.save('extractable.pdf')
Solution 5
It has nothing to do with whether the file has been decrypted or not when using the method getNumPages()
.
If we take a look at the source code of getNumPages()
:
def getNumPages(self):
"""
Calculates the number of pages in this PDF file.
:return: number of pages
:rtype: int
:raises PdfReadError: if file is encrypted and restrictions prevent
this action.
"""
# Flattened pages will not work on an Encrypted PDF;
# the PDF file's page count is used in this case. Otherwise,
# the original method (flattened page count) is used.
if self.isEncrypted:
try:
self._override_encryption = True
self.decrypt('')
return self.trailer["/Root"]["/Pages"]["/Count"]
except:
raise utils.PdfReadError("File has not been decrypted")
finally:
self._override_encryption = False
else:
if self.flattenedPages == None:
self._flatten()
return len(self.flattenedPages)
we will notice that it is the self.isEncrypted
property controlling the flow. And as we all know the isEncrypted
property is read-only and not changeable even when the pdf is decrypted.
So, the easy way to handle the situation is just add the password as key-word argument with empty string as default value and pass your password when using the getNumPages()
method and any other method build beyond it
Related videos on Youtube
Jin Lee
University of Waterloo Mechatronics Engineering Class of 2018 Here to help out with random topics in coding :) So far have worked as a Full Stack Developer at 2 startups. Python | Javascript | HTML & CSS | C++ | Java | ROBOTC | SQL | MongoDB
Updated on July 09, 2022Comments
-
Jin Lee almost 2 years
Currently I am using the PyPDF 2 as a dependency.
I have encountered some encrypted files and handled them as you normally would (in the following code):
PDF = PdfFileReader(file(pdf_filepath, 'rb')) if PDF.isEncrypted: PDF.decrypt("") print PDF.getNumPages()
My filepath looks something like "~/blah/FDJKL492019 21490 ,LFS.pdf" PDF.decrypt("") returns 1, which means it was successful. But when it hits print PDF.getNumPages(), it still raises the error, "PyPDF2.utils.PdfReadError: File has not been decrypted".
How do I get rid of this error? I can open the PDF file just fine by double click (which default-opens with Adobe Reader).
-
Jongware over 9 yearsWell spotted! It must be a limitation of Python or this particular library in particular (it has nothing to do with the PDF format). You may want to mention this on the site from where you got it.
-
Somnath Kadam over 3 yearsThanks it work for me, provided whole solution in below thread.
-
Martin Thoma almost 2 yearsThis is not / no longer the case with
PyPDF2==2.3.1
(see issue 144)