Open a protected pdf file in python - python

I write a pdf cracking and found the password of the protected pdf file. I want to write a program in Python that can display that pdf file on the screen without password.I use the PyPDF library.
I know how to open a file without the password, but can't figure out the protected one.Any idea? Thanks
filePath = raw_input()
password = 'abc'
if sys.platform.startswith('linux'):
subprocess.call(["xdg-open", filePath])

The approach shown by KL84 basically works, but the code is not correct (it writes the output file for each page). A cleaned up version is here:
https://gist.github.com/bzamecnik/1abb64affb21322256f1c4ebbb59a364
# Decrypt password-protected PDF in Python.
#
# Requirements:
# pip install PyPDF2
from PyPDF2 import PdfFileReader, PdfFileWriter
def decrypt_pdf(input_path, output_path, password):
with open(input_path, 'rb') as input_file, \
open(output_path, 'wb') as output_file:
reader = PdfFileReader(input_file)
reader.decrypt(password)
writer = PdfFileWriter()
for i in range(reader.getNumPages()):
writer.addPage(reader.getPage(i))
writer.write(output_file)
if __name__ == '__main__':
# example usage:
decrypt_pdf('encrypted.pdf', 'decrypted.pdf', 'secret_password')

You should use pikepdf library nowadays instead:
import pikepdf
with pikepdf.open("input.pdf", password="abc") as pdf:
num_pages = len(pdf.pages)
print("Total pages:", num_pages)
PyPDF2 doesn't support many encryption algorithms, pikepdf seems to solve them, it supports most of password protected methods, and also documented and actively maintained.

You can use pdfplumber library. Super easy to use and reads machine written pdf files seamlessly, better than any other library i have used.
import pdfplumber
with pdfplumber.open(r'D:\examplepdf.pdf' , password = 'abc') as pdf:
first_page = pdf.pages[0]
print(first_page.extract_text())

I have the answer for this question. Basically, the PyPDF2 library needs to install and use in order to get this idea working.
#When you have the password = abc you have to call the function decrypt in PyPDF to decrypt the pdf file
filePath = raw_input("Enter pdf file path: ")
f = PdfFileReader(file(filePath, "rb"))
output = PdfFileWriter()
f.decrypt ('abc')
# Copy the pages in the encrypted pdf to unencrypted pdf with name noPassPDF.pdf
for pageNumber in range (0, f.getNumPages()):
output.addPage(f.getPage(pageNumber))
# write "output" to noPassPDF.pdf
outputStream = file("noPassPDF.pdf", "wb")
output.write(outputStream)
outputStream.close()
#Open the file now
if sys.platform.startswith('darwin'):#open in MAC OX
subprocess.call(["open", "noPassPDF.pdf"])

Related

PyPDF2 error "PyCryptodome is required for AES algorithm"

I've got hundreds on PDFs I need to set password. I tried to use pyPDF2 to do that but I got an error:
"DependencyError: PyCryptodome is required for AES algorithm".
I've tried to google any other module like pikepdf but I found only how to crack the password using it and not to actually set password.
Any ideas how to deal with it? I get an error on that line: "input_pdf = PdfFileReader(in_file)"
file = directory + '\\passwords.xlsx'
df = pd.read_excel(file)
df['PDF'] = df.iloc[:,[0]] + '.pdf'
df = df.to_dict('records')
for i in df:
filename = i['PDF']
password = i['Password']
with open(filename, "rb") as in_file:
input_pdf = PdfFileReader(in_file)
output_pdf = PdfFileWriter()
output_pdf.appendPagesFromReader(input_pdf)
output_pdf.encrypt(password)
with open(filename, "wb") as out_file:
output_pdf.write(out_file)
I had the same problem.
You just need to install PyCryptodome package.
For example:
pip install pycryptodome==3.15.0
A.) Great way to do it:
https://roytuts.com/how-to-encrypt-pdf-as-password-protected-file-in-python/
import PyPDF2
#pdf_in_file = open("simple.pdf",'rb')
pdf_in_file = open("gre_research_validity_data.pdf",'rb')
inputpdf = PyPDF2.PdfFileReader(pdf_in_file)
pages_no = inputpdf.numPages
output = PyPDF2.PdfFileWriter()
for i in range(pages_no):
inputpdf = PyPDF2.PdfFileReader(pdf_in_file)
output.addPage(inputpdf.getPage(i))
output.encrypt('password')
#with open("simple_password_protected.pdf", "wb") as outputStream:
with open("gre_research_validity_data_password_protected.pdf", "wb") as outputStream:
output.write(outputStream)
pdf_in_file.close()
B.) If you want to fix your own bug:
solution for similar error message but during counting pages - Not able to find number of pages of PDF using Python 3.X: DependencyError: PyCryptodome is required for AES algorithm
ORIGINAL CODE
! pip install PyPDF2
! pip install pycryptodome
from PyPDF2 import PdfFileReader
from Crypto.Cipher import AES
if PdfFileReader('Media Downloaded Files/spk-10-3144 bro.pdf').isEncrypted:
print('This file is encrypted.')
else:
print(PdfFileReader('Media Downloaded Files/spk-10-3144-bro.pdf').numPages)
FIX
! pip install pikepdf
from pikepdf import Pdf
pdf = Pdf.open('Media Downloaded Files/spk-10-3144-bro.pdf')
len(pdf.pages)

Encrypt pdf file so copy content or edit is not allowed

How can I encrypt the document so it is not allowed to edit text or should not allow copying content from pdf files?
I tried setting different user and admin passwords but still, I was able to edit the text in pdf editor.
import pikepdf
from pikepdf import Pdf
pdf = Pdf.open("document.pdf")
pdf.save('output_filename.pdf', encryption=pikepdf.Encryption(owner="password", user="123", R=6))
pdf.close()
Basically if there is way without password if I can encrypt document to edit than that will well and good. Thanks in Advance.
You need to PyPDF2 (pip install PyPDF2) for using this script. And try this:
import PyPDF2
#pdf_in_file = open("document.pdf",'rb')
pdf_in_file = open("document.pdf",'rb')
inputpdf = PyPDF2.PdfFileReader(pdf_in_file)
pages_no = inputpdf.numPages
output = PyPDF2.PdfFileWriter()
for i in range(pages_no):
inputpdf = PyPDF2.PdfFileReader(pdf_in_file)
output.addPage(inputpdf.getPage(i))
output.encrypt('password_u_want')
#with open("simple_password_protected.pdf", "wb") as outputStream:
with open("output_filename.pdf", "wb") as outputStream:
output.write(outputStream)
pdf_in_file.close()
Here details for PyPDF2: https://pythonhosted.org/PyPDF2/PdfFileWriter.html

Reading pdf files line by line using python

I used the following code to read the pdf file, but it does not read it. What could possibly be the reason?
from PyPDF2 import PdfFileReader
reader = PdfFileReader("example.pdf")
contents = reader.pages[0].extractText().split("\n")
print(contents)
The output is [u''] instead of reading the content.
import re
from PyPDF2 import PdfFileReader
reader = PdfFileReader("example.pdf")
for page in reader.pages:
text = page.extractText()
text_lower = text.lower()
for line in text_lower:
if re.search("abc", line):
print(line)
I use it to iterate page by page of pdf and search for key terms in it and process further.
May be this can help you to read PDF.
import pyPdf
def getPDFContent(path):
content = ""
pages = 10
p = file(path, "rb")
pdf_content = pyPdf.PdfFileReader(p)
for i in range(0, pages):
content += pdf_content.getPage(i).extractText() + "\n"
content = " ".join(content.replace(u"\xa0", " ").strip().split())
return content
I think you need to specify the disc name, it's missing in your directory. For example "D:/Users/Rahul/Desktop/Dfiles/106_2015_34-76357.pdf". I tried and I can read without any problem.
Or if you want to find the file path using the os module which you didn't really associate with your directory, you can try the following:
from PyPDF2 import PdfFileReader
import os
def find(name, path):
for root, dirs, files in os.walk(path):
if name in files:
return os.path.join(root, name)
directory = find('106_2015_34-76357.pdf', 'D:/Users/Rahul/Desktop/Dfiles/')
f = open(directory, 'rb')
reader = PdfFileReader(f)
contents = reader.getPage(0).extractText().split('\n')
f.close()
print(contents)
The find function can be found in Nadia Alramli's answer here Find a file in python
To Read the files from Multiple Folders in a directory, below code can be used-
This Example is for reading pdf files:
import os
from tika import parser
path = "/usr/local/" # path directory
directory=os.path.join(path)
for r,d,f in os.walk(directory): #going through subdirectories
for file in f:
if ".pdf" in file: # reading only PDF files
file_join = os.path.join(r, file) #getting full path
file_data = parser.from_file(file_join) # parsing the PDF file
text = file_data['content'] # read the content
print(text) #print the content
def getTextPDF(pdfFileName,password=''):
import PyPDF2
from PyPDF2 import PdfFileReader, PdfFileWriter
from nltk import sent_tokenize
""" Extract Text from pdf """
pdf_file=open(pdfFileName,'rb')
read_pdf=PyPDF2.PdfFileReader(pdf_file)
if password !='':
read_pdf.decrypt(password)
text=[]
for i in range(0,read_pdf.getNumPages()):
text.append(read_pdf.getPage(i).extractText())
text = '\n'.join (text).replace("\n",'')
text = sent_tokenize(text)
return text
The issue was one of two things: (1) The text was not on page one - hence a user error. (2) PyPDF2 failed to extract the text - hence a bug in PyPDF2.
Sadly, the second one still happens for some PDFs.
Hello Rahul Pipalia,
If not install PyPDF2 in your python so first install PyPDF2 after use this module.
Installation Steps for Ubuntu (Install python-pypdf)
First, open terminal
After type sudo apt-get install python-pypdf
Your Probelm Solution
Try this below code,
# Import Library
import PyPDF2
# Which you want to read file so give file name with ".pdf" extension
pdf_file = open('Your_Pdf_File_Name.pdf')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
#Give page number of the pdf file (How many page in pdf file).
# #param Page_Nuber_of_the_PDF_file: Give page number here i.e 1
page = read_pdf.getPage(Page_Nuber_of_the_PDF_file)
page_content = page.extractText()
# Display content of the pdf
print page_content
Download the PDF from below link and try this code,
https://www.dropbox.com/s/4qad66r2361hvmu/sample.pdf?dl=1
I hope my answer is helpful.
If any query so comments, please.

How to decode a pdf encrypted file from python

I have got a PDF file and associated password.
I would to convert an encrypted file to a clear version using python only.
I found here some python modules (pyPdf2 , PDFMiner)
to treat PDF file but none of them will work with encryption.
Someone have already done this ?
Now pyPDF2 support encryption, according to this answer, it may be implemented like this:
import os
import PyPDF2
from PyPDF2 import PdfFileReader
fp = open(filename)
pdfFile = PdfFileReader(fp)
password = "mypassword"
if pdfFile.isEncrypted:
try:
pdfFile.decrypt(password)
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)')
fp = open(filename)
pdfFile = PdfFileReader(fp)
else:
print('File Not Encrypted')
Note that this code, use pyPDF2 by default and failback to qpdf in case of issue.
You'd also need to know the encryption algorithm and key length to be able to advise which tool might work... and depending on the answers, a python library may not be available.

merging pdf files with pypdf

I am writing a script that parses an internet site (maya.tase.co.il) for links, downloads pdf file and merges them. It works mostly, but merging gives me different kinds of errors depending on the file. I cant seem to figure out why. I cut out the relevant code and built a test only for two specific files that are causing a problem. The script uses pypdf, but I am willing to try anything that works. Some files are encrypted, some are not.
def is_incry(pdf):
from pyPdf import PdfFileWriter, PdfFileReader
input=PdfFileReader(pdf)
try:
input.getNumPages()
return input
except:
input.decrypt("")
return input
def merg_pdf(to_keep,to_lose):
import os
from pyPdf import PdfFileWriter, PdfFileReader
if os.path.exists(to_keep):
in1=file(to_keep, "rb")
in2=file(to_lose, "rb")
input1 = is_incry(in1)
input2 = is_incry(in2)
output = PdfFileWriter()
loop1=input1.getNumPages()
for i in range(0,loop1):
output.addPage(input1.getPage(i))#
loop2=input2.getNumPages()
for i in range(0,loop2):
output.addPage(input2.getPage(i))#
outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()
pdflen=loop1+loop2
in1.close()
in2.close()
os.remove(to_lose)
os.remove(to_keep)
os.rename("document-output.pdf",to_keep)
else:
os.rename(to_lose,to_keep)
in1=file(to_keep, "rb")
input1 = PdfFileReader(in1)
try:
pdflen=input1.getNumPages()
except:
input1.decrypt("")
pdflen=input1.getNumPages()
in1.close()
#input1.close()
return pdflen
def test():
import urllib
urllib.urlretrieve ('http://mayafiles.tase.co.il/RPdf/487001-488000/P487028-01.pdf', 'temp1.pdf')
urllib.urlretrieve ('http://mayafiles.tase.co.il/RPdf/488001-489000/P488170-00.pdf', 'temp2.pdf')
merg_pdf('temp1.pdf','temp2.pdf')
test()
I thank anyone that even took the time to read this.
Al.
I once wrote a complex PDF generation/merging stuff which I have now open-sourced.
You can have a look at it: https://github.com/becomingGuru/nikecup/blob/master/reg/models.py#L71
def merge_pdf(self):
from pyPdf import PdfFileReader,PdfFileWriter
pdf_file = file_names['main_pdf']%settings.MEDIA_ROOT
pdf_obj = PdfFileReader(open(pdf_file))
values_page = PdfFileReader(open(self.make_pdf())).getPage(0)
mergepage = pdf_obj.pages[0]
mergepage.mergePage(values_page)
signed_pdf = PdfFileWriter()
for page in pdf_obj.pages:
signed_pdf.addPage(page)
signed_pdf_name = file_names['dl_done']%(settings.MEDIA_ROOT,self.phash)
signed_pdf_file = open(signed_pdf_name,mode='wb')
signed_pdf.write(signed_pdf_file)
signed_pdf_file.close()
return signed_pdf_name
It then works like a charm. Hope it helps.
I tried the documents with pyPdf - it looks like both the pdfs in this document are encrypted, and a blank password ("") is not valid.
Looking at the security settings in adobe, you're allowed to print and copy - however, when you run pyPdf's input.decrypt(""), the files are still encrypted (as in, input.getNumPages() after this still returns 0).
I was able to open this in OSX's preview, and save the pdfs without encryption, and then the assembly works fine. pyPdf deals in pages though, so I don't think you can do this through pyPdf. Either find the correct password, or perhaps use another application, such as using a batch job to OpenOffice, or another pdf plugin would work.

Categories