Fuzzu FastEncrypt – AES-256-GCM File Encryptor/Decryptor in Python (Fast GUI)
Demo :
Click Video πππ
Features:
-
Large Thumbnail Image
-
Auto Read More Jump Break
-
SEO-friendly Meta Tags with keywords "Python AES-256 Encryption GUI, Fast File Encryptor, FuzzuTech
Code :
# Fuzzu FastEncrypt – AES-256-GCM File Encryptor/Decryptor (Fast + GUI)
# Author: FuzzuTech (fixed)
# Requires: pip install cryptography customtkinter
import os
import threading
import time
from tkinter import filedialog, messagebox
import customtkinter as ctk
import base64
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
# --- constants ---
MAGIC = b"FZENC1\n\x00" # 8 bytes (file signature)
SALT_LEN = 16
NONCE_LEN = 12
TAG_LEN = 16
CHUNK_SIZE = 8 * 1024 * 1024 # 8 MB
PBKDF2_ITERS = 300_000
backend = default_backend()
def rand_bytes(n: int) -> bytes:
return os.urandom(n)
def derive_key(password: str, salt: bytes) -> bytes:
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=PBKDF2_ITERS,
backend=backend,
)
return kdf.derive(password.encode("utf-8"))
def human_bytes(n: int) -> str:
n_float = float(n)
for unit in ["B", "KB", "MB", "GB", "TB"]:
if n_float < 1024.0 or unit == "TB":
return f"{n_float:.2f} {unit}"
n_float /= 1024.0
return f"{n:.2f} B"
def encrypt_file(in_path: str, out_path: str, password: str, progress_cb=None, speed_cb=None, cancel_cb=None):
total = os.path.getsize(in_path)
salt = rand_bytes(SALT_LEN)
key = derive_key(password, salt)
nonce = rand_bytes(NONCE_LEN)
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce), backend=backend)
encryptor = cipher.encryptor()
t0 = time.time()
bytes_done = 0
with open(in_path, "rb", buffering=0) as fin, open(out_path, "wb", buffering=0) as fout:
# header
fout.write(MAGIC)
fout.write(salt)
fout.write(nonce)
while True:
if cancel_cb and cancel_cb():
raise Exception("Operation cancelled by user")
chunk = fin.read(CHUNK_SIZE)
if not chunk:
break
ct = encryptor.update(chunk)
if ct:
fout.write(ct)
bytes_done += len(chunk)
if progress_cb and total > 0:
progress_cb(bytes_done / total)
if speed_cb:
dt = time.time() - t0
if dt > 0:
speed_cb(bytes_done / dt)
encryptor.finalize()
tag = encryptor.tag
fout.write(tag)
def decrypt_file(in_path: str, out_path: str, password: str, progress_cb=None, speed_cb=None, cancel_cb=None):
total = os.path.getsize(in_path)
min_size = len(MAGIC) + SALT_LEN + NONCE_LEN + TAG_LEN
if total < min_size:
raise ValueError("File too small or not an FZENC1 file")
with open(in_path, "rb", buffering=0) as fin:
header = fin.read(len(MAGIC) + SALT_LEN + NONCE_LEN)
magic = header[: len(MAGIC)]
if magic != MAGIC:
raise ValueError("Invalid file header (not FZENC1)")
salt = header[len(MAGIC) : len(MAGIC) + SALT_LEN]
nonce = header[len(MAGIC) + SALT_LEN : len(MAGIC) + SALT_LEN + NONCE_LEN]
key = derive_key(password, salt)
ct_len = total - (len(MAGIC) + SALT_LEN + NONCE_LEN + TAG_LEN)
if ct_len < 0:
raise ValueError("Corrupted file: negative ciphertext length")
with open(in_path, "rb", buffering=0) as ftag:
ftag.seek(total - TAG_LEN)
tag = ftag.read(TAG_LEN)
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce, tag), backend=backend)
decryptor = cipher.decryptor()
t0 = time.time()
bytes_done = 0
remaining = ct_len
fin.seek(len(MAGIC) + SALT_LEN + NONCE_LEN)
with open(out_path, "wb", buffering=0) as fout:
while remaining > 0:
if cancel_cb and cancel_cb():
raise Exception("Operation cancelled by user")
to_read = CHUNK_SIZE if remaining >= CHUNK_SIZE else remaining
chunk = fin.read(to_read)
if not chunk:
break
pt = decryptor.update(chunk)
if pt:
fout.write(pt)
bytes_done += len(chunk)
remaining -= len(chunk)
if progress_cb and ct_len > 0:
progress_cb(bytes_done / ct_len)
if speed_cb:
dt = time.time() - t0
if dt > 0:
speed_cb(bytes_done / dt)
decryptor.finalize()
# --------------------- GUI (CustomTkinter) ---------------------
class FastEncryptGUI(ctk.CTk):
def __init__(self):
super().__init__()
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("green")
self.title("Fuzzu FastEncrypt – AES-256-GCM")
self.geometry("500x520")
self.minsize(500, 480)
self.file_path = ctk.StringVar()
self.out_dir = ctk.StringVar()
self.password = ctk.StringVar()
self.mode = ctk.StringVar(value="Encrypt")
self.status = ctk.StringVar(value="Ready")
self.speed = ctk.StringVar(value="Speed: 0 MB/s")
self.size_info = ctk.StringVar(value="File: –")
self.job_thread = None
self.cancel_requested = False
self.showing = False
self.build_ui()
def build_ui(self):
pad = 12
title = ctk.CTkLabel(self, text="Fuzzu FastEncrypt", font=("Segoe UI", 26, "bold"))
title.pack(pady=(16, 6))
subtitle = ctk.CTkLabel(self, text="AES-256-GCM • Fast Encrypt/Decrypt • Authenticated", font=("Segoe UI", 14))
subtitle.pack(pady=(0, 14))
row = ctk.CTkFrame(self)
row.pack(fill="x", padx=pad, pady=(0, pad))
entry = ctk.CTkEntry(row, textvariable=self.file_path, placeholder_text="Choose file to encrypt/decrypt")
entry.pack(side="left", fill="x", expand=True, padx=(pad, 6), pady=pad)
pick = ctk.CTkButton(row, text="Browse", command=self.choose_file)
pick.pack(side="right", padx=(0, pad), pady=pad)
row2 = ctk.CTkFrame(self)
row2.pack(fill="x", padx=pad, pady=(0, pad))
out_entry = ctk.CTkEntry(row2, textvariable=self.out_dir, placeholder_text="Select output folder (optional)")
out_entry.pack(side="left", fill="x", expand=True, padx=(pad, 6), pady=pad)
pick2 = ctk.CTkButton(row2, text="Folder", command=self.choose_dir)
pick2.pack(side="right", padx=(0, pad), pady=pad)
row3 = ctk.CTkFrame(self)
row3.pack(fill="x", padx=pad, pady=(0, pad))
pwd = ctk.CTkEntry(row3, textvariable=self.password, show="*", placeholder_text="Enter strong password")
pwd.pack(side="left", fill="x", expand=True, padx=(pad, 6), pady=pad)
eye = ctk.CTkButton(row3, text="π", width=48, command=lambda: self.toggle_pwd(pwd))
eye.pack(side="right", padx=(0, pad), pady=pad)
row4 = ctk.CTkFrame(self)
row4.pack(fill="x", padx=pad, pady=(0, pad))
mode_opt = ctk.CTkOptionMenu(row4, values=["Encrypt", "Decrypt"], variable=self.mode)
mode_opt.pack(side="left", padx=(pad, 6), pady=pad)
go = ctk.CTkButton(row4, text="Start", command=self.start_action)
go.pack(side="left", padx=(0, 6), pady=pad)
cancel = ctk.CTkButton(row4, text="Cancel", fg_color="#444", command=self.cancel_job)
cancel.pack(side="left", padx=(0, pad), pady=pad)
self.progress = ctk.CTkProgressBar(self)
self.progress.set(0)
self.progress.pack(fill="x", padx=pad, pady=(6, 6))
info_row = ctk.CTkFrame(self)
info_row.pack(fill="x", padx=pad, pady=(0, 6))
self.status_lbl = ctk.CTkLabel(info_row, textvariable=self.status)
self.status_lbl.pack(side="left", padx=(pad, 6), pady=6)
self.speed_lbl = ctk.CTkLabel(info_row, textvariable=self.speed)
self.speed_lbl.pack(side="right", padx=(6, pad), pady=6)
self.size_lbl = ctk.CTkLabel(self, textvariable=self.size_info, font=("Segoe UI", 12))
self.size_lbl.pack(pady=(0, 10))
foot = ctk.CTkLabel(self, text="Tip: AES-GCM is hardware-accelerated on most CPUs. Use SSD for maximum speed.")
foot.pack(pady=(0, 10))
def toggle_pwd(self, entry):
self.showing = not self.showing
entry.configure(show="" if self.showing else "*")
def choose_file(self):
p = filedialog.askopenfilename()
if p:
self.file_path.set(p)
try:
sz = os.path.getsize(p)
self.size_info.set(f"File: {os.path.basename(p)} ({human_bytes(sz)})")
except Exception:
self.size_info.set("File: –")
def choose_dir(self):
d = filedialog.askdirectory()
if d:
self.out_dir.set(d)
def update_progress(self, frac):
frac = max(0.0, min(1.0, frac))
self.after(0, lambda: self.progress.set(frac))
def update_speed(self, bps):
mbps = bps / (1024 * 1024)
text = f"Speed: {mbps:.2f} MB/s"
self.after(0, lambda: self.speed.set(text))
def set_status(self, text):
self.after(0, lambda: self.status.set(text))
def start_action(self):
path = self.file_path.get().strip()
if not path:
messagebox.showwarning("Select file", "Please choose a file first.")
return
if not os.path.isfile(path):
messagebox.showerror("Invalid", "Selected file does not exist.")
return
pwd = self.password.get()
if not pwd or len(pwd) < 6:
messagebox.showwarning("Weak Password", "Please enter a strong password (6+ characters).")
return
out_dir = self.out_dir.get().strip() or os.path.dirname(path)
base = os.path.basename(path)
mode = self.mode.get()
if mode == "Encrypt":
out_name = base + ".fzenc"
out_path = os.path.join(out_dir, out_name)
action_func = lambda cancel_cb: encrypt_file(path, out_path, pwd, self.update_progress, self.update_speed, cancel_cb)
else:
if base.endswith(".fzenc"):
out_name = base[:-6]
else:
out_name = base + ".dec"
out_path = os.path.join(out_dir, out_name)
action_func = lambda cancel_cb: decrypt_file(path, out_path, pwd, self.update_progress, self.update_speed, cancel_cb)
if os.path.abspath(path) == os.path.abspath(out_path):
messagebox.showerror("Output conflict", "Output file would overwrite input. Choose a different folder.")
return
self.cancel_requested = False
self.set_status(f"{mode}ing…")
self.progress.set(0)
self.speed.set("Speed: 0 MB/s")
def worker():
try:
action_func(lambda: self.cancel_requested)
self.set_status(f"{mode} complete ✓")
self.after(0, lambda: self.progress.set(1.0))
except Exception as e:
if str(e) == "Operation cancelled by user":
self.set_status("Cancelled")
messagebox.showinfo("Cancelled", "Operation cancelled.")
else:
self.set_status(f"Error: {e}")
messagebox.showerror("Failed", str(e))
finally:
self.job_thread = None
self.cancel_requested = False
self.job_thread = threading.Thread(target=worker, daemon=True)
self.job_thread.start()
def cancel_job(self):
if self.job_thread and self.job_thread.is_alive():
self.cancel_requested = True
self.set_status("Cancelling… (waiting for current chunk to finish)")
else:
messagebox.showinfo("Cancel", "No active job to cancel.")
if __name__ == "__main__":
app = FastEncryptGUI()
app.mainloop()
Comments
Post a Comment