import tkinter as tk from tkinter import ttk, filedialog, messagebox import os from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import hashes, padding from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.backends import default_backend import secrets class Encrypto: def __init__(self, root): self.root = root self.root.title("Encrypto") self.root.geometry("500x500") self.root.resizable(True, True) self.selected_file = tk.StringVar() self.password = tk.StringVar() self.algorithm = tk.StringVar(value="AES-256") self.operation = tk.StringVar(value="encrypt") self.setup_ui() def setup_ui(self): main_frame = ttk.Frame(self.root, padding="20") main_frame.grid(row=0, column=0, sticky="nsew") self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) main_frame.columnconfigure(1, weight=1) ttk.Label(main_frame, text="Select File:").grid( row=0, column=0, sticky="w", pady=5 ) file_frame = ttk.Frame(main_frame) file_frame.grid(row=0, column=1, sticky="ew", pady=5) file_frame.columnconfigure(0, weight=1) self.file_entry = ttk.Entry( file_frame, textvariable=self.selected_file, state="readonly" ) self.file_entry.grid(row=0, column=0, sticky="ew", padx=(0, 5)) ttk.Button(file_frame, text="Browse", command=self.browse_file).grid( row=0, column=1 ) ttk.Label(main_frame, text="Algorithm:").grid( row=1, column=0, sticky="w", pady=5 ) algo_combo = ttk.Combobox( main_frame, textvariable=self.algorithm, values=["AES-256", "AES-128"], state="readonly", ) algo_combo.grid(row=1, column=1, sticky="ew", pady=5) ttk.Label(main_frame, text="Operation:").grid( row=2, column=0, sticky="w", pady=5 ) op_frame = ttk.Frame(main_frame) op_frame.grid(row=2, column=1, sticky="ew", pady=5) ttk.Radiobutton( op_frame, text="Encrypt", variable=self.operation, value="encrypt" ).grid(row=0, column=0, sticky="w") ttk.Radiobutton( op_frame, text="Decrypt", variable=self.operation, value="decrypt" ).grid(row=0, column=1, sticky="w", padx=(20, 0)) ttk.Label(main_frame, text="Password:").grid( row=3, column=0, sticky="w", pady=5 ) self.password_entry = ttk.Entry( main_frame, textvariable=self.password, show="*" ) self.password_entry.grid(row=3, column=1, sticky="ew", pady=5) self.show_password = tk.BooleanVar() ttk.Checkbutton( main_frame, text="Show password", variable=self.show_password, command=self.toggle_password, ).grid(row=4, column=1, sticky="w", pady=5) self.process_btn = ttk.Button( main_frame, text="Encrypt", command=self.process_file ) self.process_btn.grid(row=5, column=0, columnspan=2, sticky="ew", pady=20) self.progress = ttk.Progressbar(main_frame, mode="indeterminate") self.progress.grid(row=6, column=0, columnspan=2, sticky="ew", pady=5) self.status_text = tk.Text(main_frame, height=8, width=50) self.status_text.grid(row=7, column=0, columnspan=2, sticky="nsew", pady=5) scrollbar = ttk.Scrollbar( main_frame, orient="vertical", command=self.status_text.yview ) scrollbar.grid(row=7, column=2, sticky="ns", pady=5) self.status_text.configure(yscrollcommand=scrollbar.set) main_frame.rowconfigure(7, weight=1) self.operation.trace_add("write", self.update_button_text) def browse_file(self): if self.operation.get() == "encrypt": filename = filedialog.askopenfilename( title="Select file to encrypt", filetypes=[("All files", "*.*")] ) else: filename = filedialog.askopenfilename( title="Select file to decrypt", filetypes=[("Encrypted files", "*.enc"), ("All files", "*.*")], ) if filename: self.selected_file.set(filename) def toggle_password(self): if self.show_password.get(): self.password_entry.configure(show="") else: self.password_entry.configure(show="*") def update_button_text(self, *args): if self.operation.get() == "encrypt": self.process_btn.configure(text="Encrypt") else: self.process_btn.configure(text="Decrypt") def log_status(self, message): self.status_text.insert(tk.END, message + "\n") self.status_text.see(tk.END) self.root.update() def derive_key(self, password, salt): key_length = 32 if self.algorithm.get() == "AES-256" else 16 kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=key_length, salt=salt, iterations=100000, backend=default_backend(), ) return kdf.derive(password.encode()) def encrypt_file(self, input_file, output_file, password): try: salt = secrets.token_bytes(16) iv = secrets.token_bytes(16) key = self.derive_key(password, salt) cipher = Cipher( algorithms.AES(key), modes.CBC(iv), backend=default_backend() ) encryptor = cipher.encryptor() padder = padding.PKCS7(128).padder() with open(input_file, "rb") as infile, open(output_file, "wb") as outfile: outfile.write(salt) outfile.write(iv) while True: chunk = infile.read(8192) if not chunk: padded_data = padder.finalize() if padded_data: outfile.write(encryptor.update(padded_data)) outfile.write(encryptor.finalize()) break padded_chunk = padder.update(chunk) outfile.write(encryptor.update(padded_chunk)) return True except Exception as e: self.log_status(f"Encryption error: {str(e)}") return False def decrypt_file(self, input_file, output_file, password): try: with open(input_file, "rb") as infile: salt = infile.read(16) iv = infile.read(16) key = self.derive_key(password, salt) cipher = Cipher( algorithms.AES(key), modes.CBC(iv), backend=default_backend() ) decryptor = cipher.decryptor() unpadder = padding.PKCS7(128).unpadder() with open(output_file, "wb") as outfile: while True: chunk = infile.read(8192) if not chunk: break decrypted_chunk = decryptor.update(chunk) if decrypted_chunk: unpadded_chunk = unpadder.update(decrypted_chunk) if unpadded_chunk: outfile.write(unpadded_chunk) if hasattr(self, "root"): self.root.update() final_decrypted = decryptor.finalize() if final_decrypted: final_unpadded = unpadder.update(final_decrypted) if final_unpadded: outfile.write(final_unpadded) final_unpadded = unpadder.finalize() if final_unpadded: outfile.write(final_unpadded) return True except Exception as e: self.log_status(f"Decryption error: {str(e)}") return False def process_file(self): if not self.selected_file.get(): messagebox.showerror("Error", "Please select a file") return if not self.password.get(): messagebox.showerror("Error", "Please enter a password") return if not os.path.exists(self.selected_file.get()): messagebox.showerror("Error", "Selected file does not exist") return self.progress.start() self.process_btn.configure(state="disabled") input_file = self.selected_file.get() operation = self.operation.get() if operation == "encrypt": output_file = input_file + ".enc" self.log_status( f"Starting encryption of: {os.path.basename(input_file)}..." ) self.log_status(f"Algorithm: {self.algorithm.get()}") success = self.encrypt_file(input_file, output_file, self.password.get()) if success: self.log_status("✓ File encrypted successfully!") self.log_status( f"Encrypted file saved as: {os.path.basename(output_file)}" ) messagebox.showinfo( "Success", f"File encrypted successfully!\nSaved as: {output_file}" ) else: messagebox.showerror( "Error", "Encryption failed. Check the status log for details." ) else: if input_file.endswith(".enc"): output_file = input_file[:-4] else: output_file = input_file + ".decrypted" self.log_status( f"Starting decryption of: {os.path.basename(input_file)}..." ) success = self.decrypt_file(input_file, output_file, self.password.get()) if success: self.log_status("✓ File decrypted successfully!") self.log_status( f"Decrypted file saved as: {os.path.basename(output_file)}" ) messagebox.showinfo( "Success", f"File decrypted successfully!\nSaved as: {output_file}" ) else: messagebox.showerror( "Error", "Decryption failed. Check password and try again." ) self.progress.stop() self.process_btn.configure(state="normal") def main(): root = tk.Tk() Encrypto(root) root.mainloop() if __name__ == "__main__": main()