Encrypt and Decrypt PDF Files in Python using Tkinter

An image displaying two bold-text labels, 'Encrypt' and 'Decrypt,' with a PDF file depicted below them. The PDF file is surrounded by lock and unlock symbols, indicating encryption and decryption, and is associated with a Python logo.

Introduction

In today’s digital age, securing sensitive information is very important. One of the most common techniques is encrypting digital data. PDF (Portable Document Format) files are widely used for sharing documents because of their consistent formatting across different devices and platforms. Since it can hold a lot of sensitive information, encrypting a PDF file is a smart idea.

In this article, we will create a Python application using the Tkinter library to encrypt and decrypt a PDF file with just a few clicks. So, let’s get started.

Requirements

Before we dive into the code, make sure you have Python installed on your computer. You’ll also need the following libraries installed on your system and a basic understanding of Python programming concepts (To learn Python, visit this page: Python Tutorials):


pip install tk
pip install PyPDF2

Import the Modules

Let’s create a Python file named “secure_pdf.py” and start writing your code by importing the following modules:


import os
from tkinter import *
from functools import partial
from tkinter import filedialog, messagebox
from PyPDF2 import PdfFileReader, PdfFileWriter

Define the PDF App Class

Create a class and give it the name `PDFApp`.


class PDFApp:

Create the Application Window

The `__init__` method will create the main application window for us. Here, we specify the window size, title, resizable option, etc.


    def __init__(self, root):
        # Setting the Tkinter main window
        self.window = root
        self.window.geometry("700x420")
        self.window.title('Encrypt & Decrypt PDFs')
        self.window.resizable(width = False, height = False)

        # Creating a Frame
        self.frame = Frame(self.window,bg="gray22",width=700,height=420)
        self.frame.place(x=0, y=0)
    
        self.main_window()

Define the Main Window

Next, create a method called `main_window`. It will include a pair of buttons labeled as “Encrypt” and “Decrypt” placed on the primary window.


    def main_window(self):
        self.clear_screen()
        # Encrypt Button
        encrypt_button = Button(self.frame, text='Encrypt',
        font=("Helvetica", 18, 'bold'), bg="red", fg="white", width=7,
        command=partial(self.select_file, 1))
        encrypt_button.place(x=280, y=130)
        
        # Decrypt Button
        decrypt_button = Button(self.frame, text='Decrypt', 
        font=("Helvetica", 18, 'bold'), bg="yellow", fg="black", 
        width=7, command=partial(self.select_file, 2))
        decrypt_button.place(x=280, y=200)

Clear the Screen

Now, let’s define a method named `clear_screen` to remove the widgets within the frame that was established during the creation of the Application Window.


    def clear_screen(self):
        for widget in self.frame.winfo_children():
            widget.destroy()

Select the PDF File

Create a separate method called `select_file` for selecting the PDF file using the Tkinter dialog box.


    def select_file(self, to_call):
        self.PDF_path = filedialog.askopenfilename(initialdir = "/", 
        title = "Select a PDF File", 
        filetypes = (("PDF files", "*.pdf*"),))
        if len(self.PDF_path) != 0:
            if to_call == 1:
                self.encrypt_password()
            else:
                self.decrypt_password()

Get the Password for Encryption

The `encrypt_password` method will present PDF details, such as the PDF file’s name and the total number of pages, while also prompting the user to input a password for encrypting the chosen PDF file.

Displayed application window featuring a 'Encrypt PDF' heading, additional text related to a selected PDF file, and a 'Encrypt' button below.

    def encrypt_password(self):
        pdfReader = PdfFileReader(self.PDF_path)
        total_pages = pdfReader.numPages

        self.clear_screen()
        # Button for getting back to the Home Page
        home_btn = Button(self.frame, text="Home", 
        font=("Helvetica", 8, 'bold'), command=self.main_window)
        home_btn.place(x=10, y=10)

        # Header Label
        header = Label(self.frame, text="Encrypt PDF", 
        font=("Kokila", 25, "bold"), bg="gray22", fg="yellow")
        header.place(x=250, y=15)

        # Label for showing the total number of pages
        pages_label = Label(self.frame, 
        text=f"Total Number of Pages: {total_pages}", 
        font=("Times New Roman", 18, 'bold'),bg="gray22",fg="white")
        pages_label.place(x=40, y=90)

        # Label for showing the filename
        name_label = Label(self.frame, 
        text=f"File Name: {os.path.basename(self.PDF_path)}", 
        font=("Times New Roman", 18, 'bold'),bg="gray22",fg="white")
        name_label.place(x=40, y=130)

        # Set Password Label
        set_password = Label(self.frame, 
        text="Set Password: ", 
        font=("Times New Roman", 18, 'bold'),bg="gray22",fg="white")
        set_password.place(x=40, y=170)
        
        # Entrybox to set the password to encrypt the PDF file
        self.set_password = Entry(self.frame, 
        font=("Helvetica, 12"), show='*')
        self.set_password.place(x=190, y=174)

        # Encrypt Button
        Encrypt_btn = Button(self.frame, text="Encrypt", 
        font=("Kokila", 10, "bold"), cursor="hand2", 
        command=self.encrypt_pdf)
        Encrypt_btn.place(x=290, y=220)

Get the Password for Decryption

The `decrypt_password` method will solely request the user to provide a password for decrypting the previously encrypted PDF file.

Displayed application window featuring a 'Decrypt PDF' heading, an 'Enter the password' label with an entry widget, and a 'Decrypt' button below.

    def decrypt_password(self):
        self.clear_screen()
        # Button for getting back to the Home Page
        home_btn = Button(self.frame, text="Home", 
        font=("Helvetica", 8, 'bold'), command=self.main_window)
        home_btn.place(x=10, y=10)

        # Header Label
        header = Label(self.frame, text="Encrypt PDF", 
        font=("Kokila", 25, "bold"), bg="gray22", fg="yellow")
        header.place(x=250, y=15)

        # Enter Password Label
        enter_password = Label(self.frame, 
        text="Enter Password: ", 
        font=("Times New Roman", 18, 'bold'), bg="gray22", fg="white")
        enter_password.place(x=40, y=170)

        # Entrybox to get the password to decrypt the PDF file
        self.ent_password = Entry(self.frame, 
        font=("Helvetica, 12"), show='*')
        self.ent_password.place(x=220, y=174)

        # Decrypt Button
        Decrypt_btn = Button(self.frame, text="Decrypt", 
        font=("Kokila", 10, "bold"), cursor="hand2", 
        command=self.decrypt_pdf)
        Decrypt_btn.place(x=290, y=220)

Adding PDF Encryption Logic

Let’s define a method called `encrypt_pdf` to incorporate the encryption logic into our program.


    def encrypt_pdf(self):
        if self.set_password.get() == '':
            messagebox.showwarning('Warning', "Please set the password")
        else:
            try:
                # Read the PDF file
                pdfFile = PdfFileReader(self.PDF_path)
                # Create a PdfFileWriter object
                pdfWriter = PdfFileWriter()
                # The Result file: Same name as the original
                result = open(self.PDF_path, 'wb')

                # Iterate through every pages of the PDF file
                for page in range(pdfFile.getNumPages()):
                    # Add the page to the pdfWriter variable
                    pdfWriter.addPage(pdfFile.getPage(page))

                # Encrypt the PDf file
                pdfWriter.encrypt(user_pwd=self.set_password.get())
                # Write the Result file
                pdfWriter.write(result)
                messagebox.showinfo('Done!',
                "The PDF file has been encrypted")
                self.main_window()
                # Set the self.PDF_path None value
                self.PDF_path = None
            except Exception as es:
                messagebox.showerror('Error!', f"Error due to {es}")

Adding PDF Decryption Logic

We have established the encryption logic. Therefore, the next step is to implement the decryption logic in our program. To achieve this, let’s create a method called `decrypt_pdf`.


    def decrypt_pdf(self):
        if self.ent_password.get() == '':
            messagebox.showwarning('Warning', "Please enter the password")
        else:
            pdf_file = open(self.PDF_path, 'rb')

            pdf_reader = PdfFileReader(pdf_file)

            if pdf_reader.isEncrypted:
                try:
                    pdf_reader.decrypt(password=self.ent_password.get())
                    
                    pdf_writer = PdfFileWriter()

                    for page_num in range(pdf_reader.numPages):
                        pdf_writer.addPage(pdf_reader.getPage(page_num))

                    # Save the decrypted PDF to a new file
                    output_file_path = filedialog.asksaveasfilename(defaultextension=".pdf", 
                    filetypes=[("PDF files", "*.pdf")])
                    if output_file_path:
                        with open(output_file_path, 'wb') as output_file:
                            pdf_writer.write(output_file)
                            messagebox.showinfo("Success", 
                            "PDF decrypted and saved successfully!")

                            self.main_window()
                            self.PDF_path = None

                except Exception as e:
                    messagebox.showerror('Error!', "Invalid password, Please try again.")

Putting it All Together

In the main part of your code, create an instance of the `PDFApp` class to build the GUI, and then start the main loop.


if __name__ == "__main__":
    root = Tk()
    obj = PDFApp(root)
    root.mainloop()

Output

Watch the complete video to understand the functionality of the application.

Summary

In this article, we’ve demonstrated how to create a Python application for encrypting and decrypting PDF files using the Tkinter library. PDF encryption is a valuable technique for protecting sensitive documents, and Python provides a straightforward way to implement it. The app used the PyPDF2 library for PDF manipulation and Tkinter for creating the GUI.

The application allows users to choose whether to encrypt or decrypt the file, select a PDF file, and input a password. If the PDF is encrypted, the app handles password validation, providing an error message for invalid passwords.

With the code provided, you can easily build a user-friendly interface to secure and access your PDF files. Always use encryption responsibly and keep your passwords secure to ensure the confidentiality of your documents. Building such an app not only strengthens Python and Tkinter skills but also adds a useful asset to the digital toolbox.

There are more projects like this available; please explore the dedicated page exclusively made for Python Projects.

Share your love
Subhankar Rakshit
Subhankar Rakshit

Hey there! I’m Subhankar Rakshit, the brains behind PySeek. I’m a Post Graduate in Computer Science. PySeek is where I channel my love for Python programming and share it with the world through engaging and informative blogs.

Articles: 194