Password Manager App Using Python

Password Manager App Using Python

Password Manager App Using Python

Step 1: Import Necessary Libraries

  • Import libraries for cryptographic functions, file handling, and GUI creation:
    import hashlib
    from base64 import b64encode, b64decode
    import os
    from Cryptodome.Cipher import AES
    from Cryptodome.Random import get_random_bytes
    import json
    import tkinter as tk
    from tkinter import filedialog, messagebox
    

Step 2: Define Encryption Function

  • Create a function encrypt to:
    1. Generate a random salt.
    2. Derive a secure private key from the password and salt using hashlib.scrypt.
    3. Use the private key with AES in GCM mode to encrypt the input message.
    4. Return the encrypted data (cipher text, salt, nonce, and tag) in a dictionary.
    def encrypt(plain_text, password):
        if not password:
            raise ValueError("Password cannot be empty.")
    
        salt = get_random_bytes(AES.block_size)
        private_key = hashlib.scrypt(
            password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32
        )
        cipher_config = AES.new(private_key, AES.MODE_GCM)
        cipher_text, tag = cipher_config.encrypt_and_digest(bytes(plain_text, "utf-8"))
        return {
            "cipher_text": b64encode(cipher_text).decode("utf-8"),
            "salt": b64encode(salt).decode("utf-8"),
            "nonce": b64encode(cipher_config.nonce).decode("utf-8"),
            "tag": b64encode(tag).decode("utf-8"),
        }
    

Step 3: Define Decryption Function

  • Create a function decrypt to:
    1. Recreate the private key from the password and salt.
    2. Decrypt the cipher text using AES in GCM mode and verify the integrity using the tag.
    3. Return the original message.
    def decrypt(enc_dict, password):
        if not password:
            raise ValueError("Password cannot be empty.")
    
        try:
            salt = b64decode(enc_dict["salt"])
            cipher_text = b64decode(enc_dict["cipher_text"])
            nonce = b64decode(enc_dict["nonce"])
            tag = b64decode(enc_dict["tag"])
            private_key = hashlib.scrypt(
                password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32
            )
            cipher = AES.new(private_key, AES.MODE_GCM, nonce=nonce)
            decrypted = cipher.decrypt_and_verify(cipher_text, tag)
            return decrypted.decode("utf-8")
        except (ValueError, KeyError) as e:
            raise ValueError("Invalid encrypted message format.") from e
    

Step 4: Add File Save Functionality

  • Create save_to_file to save encrypted data as a JSON file:
    def save_to_file(data):
        file_path = filedialog.asksaveasfilename(
            defaultextension=".json",
            filetypes=[("JSON Files", "*.json"), ("All Files", "*.*")],
        )
        if file_path:
            with open(file_path, "w") as file:
                json.dump(data, file)
            messagebox.showinfo("Success", f"Encrypted data saved to {file_path}")
    

Step 5: Add File Load Functionality

  • Create load_from_file to load encrypted data from a JSON file:
    def load_from_file():
        file_path = filedialog.askopenfilename(
            filetypes=[("JSON Files", "*.json"), ("All Files", "*.*")]
        )
        if file_path:
            with open(file_path, "r") as file:
                return json.load(file)
        else:
            raise FileNotFoundError("No file selected")
    

Step 6: Create GUI Handlers

1. Encryption Handler

  • Handle encryption and:
    • Display encrypted data.
    • Save it to a file if the user chooses.
    • Clear input fields after processing.
    def handle_encrypt():
        try:
            password = password_entry.get()
            plain_text = message_text.get("1.0", tk.END).strip()
            if not plain_text:
                raise ValueError("Message cannot be empty.")
    
            encrypted = encrypt(plain_text, password)
            result_text.delete("1.0", tk.END)
            result_text.insert(tk.END, json.dumps(encrypted, indent=4))
            if messagebox.askyesno("Save Encrypted Data", "Do you want to save the encrypted data to a file?"):
                save_to_file(encrypted)
    
            # Clear input fields
            password_entry.delete(0, tk.END)
            message_text.delete("1.0", tk.END)
    
        except Exception as e:
            messagebox.showerror("Error", str(e))
    

2. Decryption Handler

  • Handle decryption and:
    • Load encrypted data from a file.
    • Display the decrypted message.
    • Clear input fields after processing.
    def handle_decrypt():
        try:
            password = password_entry.get()
            encrypted = load_from_file()
            decrypted_message = decrypt(encrypted, password)
            result_text.delete("1.0", tk.END)
            result_text.insert(tk.END, decrypted_message)
    
            # Clear input fields
            password_entry.delete(0, tk.END)
    
        except Exception as e:
            messagebox.showerror("Error", str(e))
    

Step 7: Build the GUI

  1. Create the main window:

    root = tk.Tk()
    root.title("Secure Password Manager App")
  2. Add input fields for the password and message:

    tk.Label(root, text="Password:").grid(row=0, column=0, padx=10, pady=5)
    password_entry = tk.Entry(root, show="*", width=40)
    password_entry.grid(row=0, column=1, padx=10, pady=5)
    
    tk.Label(root, text="Message:").grid(row=1, column=0, padx=10, pady=5)
    message_text = tk.Text(root, height=10, width=50)
    message_text.grid(row=1, column=1, padx=10, pady=5)
    
  3. Add buttons for encryption and decryption:

    encrypt_button = tk.Button(root, text="Encrypt", command=handle_encrypt, width=15)
    encrypt_button.grid(row=2, column=0, padx=10, pady=10)
    
    decrypt_button = tk.Button(root, text="Decrypt", command=handle_decrypt, width=15)
    decrypt_button.grid(row=2, column=1, padx=10, pady=10)
    
  4. Add an output area to display results:

    tk.Label(root, text="Result:").grid(row=3, column=0, padx=10, pady=5)
    result_text = tk.Text(root, height=10, width=50)
    result_text.grid(row=3, column=1, padx=10, pady=5)
    
  5. Start the GUI application:

    root.mainloop()
    

Step 8: Run the Program

  • Save the complete code in a Python file (e.g., aes_gui.py).
  • Install required libraries (pip install pycryptodome).
  • Run the script:
    python3 aes_gui.py
    

Now the GUI-based program provides user-friendly encryption and decryption with field-clearing and file management functionalities!

Post Comment