Encrypt and protect your sensitive files effortlessly with Secret Keeper.
import tkinter as tk
from menu import MenuFrame
from encryptor import EncryptFrame
from decryptor import DecryptFrame

class AppManager:
    def __init__(self, root):
        self.root = root
        self.root.title("Secret Keeper")
        self.root.geometry("500x300")
        self.root.configure(background='#1d1e1f')

        self.current_frame = None

        self.menu_frame = MenuFrame(self)
        self.encrypt_frame = EncryptFrame(self)
        self.decrypt_frame = DecryptFrame(self)

        self.show_frame(self.menu_frame)

    def show_frame(self, frame):
        if self.current_frame:
            self.current_frame.pack_forget()
        self.current_frame = frame
        self.current_frame.pack()

app_manager.py
devIasminSilva/SecretKeeper
import tkinter as tk
from tkinter import filedialog, messagebox
import os
import struct
from Crypto.Cipher import AES

class DecryptFrame(tk.Frame):
    def __init__(self, app_manager):
        super().__init__(app_manager.root, bg='#1d1e1f')

        self.app_manager = app_manager

        self.file_path = tk.StringVar()
        self.key_path = tk.StringVar()

        # Background
        self.background_image = tk.PhotoImage(file='assets/backgrounds/bg.png')
        self.background_label = tk.Label(self, image=self.background_image).place(x=0, y=0, relwidth=1, relheight=1)

        tk.Label(self, text=" ", background='#1d1e1f').grid(row=0, column=0, sticky=tk.W, pady=5)

        # Procurar arquivo
        self.browse_file_image = tk.PhotoImage(file='assets/buttons/select_file.png')
        tk.Button(self, image=self.browse_file_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.browse_file).grid(row=2, column=0, sticky=tk.SW, pady=20, padx=10)
        tk.Entry(self, textvariable=self.file_path, foreground="gray", bg='#1d1e1f', bd=0).grid(row=3, column=0, columnspan=3, sticky=tk.W, ipadx=120, padx=10)

        # Procurar chave
        self.browse_key_file_image = tk.PhotoImage(file='assets/buttons/select_key_file.png')
        tk.Button(self, image=self.browse_key_file_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.browse_key_file).grid(row=4, column=0, sticky=tk.SW, pady=20, padx=10)
        tk.Entry(self, textvariable=self.key_path, foreground="gray", bg='#1d1e1f', bd=0).grid(row=5, column=0, columnspan=3, sticky=tk.W, ipadx=120, padx=10)

        # Confirmar
        self.decrypt_image = tk.PhotoImage(file='assets/buttons/confirm.png')
        tk.Button(self, image=self.decrypt_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.decrypt).grid(row=6, column=0, sticky=tk.SW, pady=40, padx=100)

        # Voltar ao menu
        self.back_image = tk.PhotoImage(file='assets/buttons/back.png')
        tk.Button(self, image=self.back_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.show_menu_frame).grid(row=6, column=0, sticky=tk.SW, pady=40, padx=0)


    ###### Funções ######

    def show_menu_frame(self):
        self.app_manager.show_frame(self.app_manager.menu_frame)

    def browse_file(self):
        file_selected = filedialog.askopenfilename()
        if file_selected:
            self.file_path.set(file_selected)

    def browse_key_file(self):
        key_file_selected = filedialog.askopenfilename()
        if key_file_selected:
            self.key_path.set(key_file_selected)

    def decrypt_file(self, key, in_filename, out_filename=None, chunksize=24*1024):
        if not out_filename:
            out_filename = os.path.splitext(in_filename)[0]

        with open(in_filename, 'rb') as infile:
            origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
            iv = infile.read(16)
            decryptor = AES.new(key, AES.MODE_CBC, iv)

            with open(out_filename, 'wb') as outfile:
                while True:
                    chunk = infile.read(chunksize)
                    if len(chunk) == 0:
                        break
                    outfile.write(decryptor.decrypt(chunk))

                outfile.truncate(origsize)

    def decrypt(self):
        file_path = self.file_path.get()
        key_path = self.key_path.get()

        if not file_path:
            messagebox.showerror("Error", "Select a folder to decrypt.")
            return

        if not key_path:
            messagebox.showerror("Error", "Select the key file.")
            return

        try:
            with open(key_path, 'rb') as key_file:
                key = key_file.read()

            out_filename = os.path.splitext(file_path)[0]
            
            with open(file_path, 'rb') as infile:
                origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
                iv = infile.read(16)
                decryptor = AES.new(key, AES.MODE_CBC, iv)

                with open(out_filename, 'wb') as outfile:
                    while True:
                        chunk = infile.read(64*1024)
                        if len(chunk) == 0:
                            break
                        outfile.write(decryptor.decrypt(chunk))

                    outfile.truncate(origsize)

            messagebox.showinfo("Success", "Folder decrypted successfully.")

        except Exception as e:
            print("Error:", str(e))
            messagebox.showerror("Error", "Decryption failed.")
decryptor.py
devIasminSilva/SecretKeeper
import tkinter as tk
from tkinter import filedialog, messagebox
import shutil
import secrets
import os
import struct
from Crypto.Cipher import AES

class EncryptFrame(tk.Frame):
    def __init__(self, app_manager):
        super().__init__(app_manager.root, bg='#1d1e1f')

        self.app_manager = app_manager

        self.folder_path = tk.StringVar()
        self.password = tk.StringVar()
        self.show_password = tk.BooleanVar()
        self.show_password.set(False)

        # Background
        self.background_image = tk.PhotoImage(file='assets/backgrounds/bg.png')
        self.background_label = tk.Label(self, image=self.background_image).place(x=0, y=0, relwidth=1, relheight=1)
    
        tk.Label(self, text=" ", background='#1d1e1f').grid(row=0, column=0, sticky=tk.W, pady=5)

        # Procurar pasta
        self.browse_folder_image = tk.PhotoImage(file='assets/buttons/select_folder.png')
        tk.Button(self, image=self.browse_folder_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.browse_folder).grid(row=2, column=0, sticky=tk.SW, pady=20, padx=10)
        tk.Entry(self, textvariable=self.folder_path, foreground='gray', bg='#1d1e1f', bd=0).grid(row=3, column=0, columnspan=3, sticky=tk.W, ipadx=120, padx=10)

        # Gerar senha
        self.generate_password_image = tk.PhotoImage(file='assets/buttons/generate_password.png')
        tk.Button(self, image=self.generate_password_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.generate_password).grid(row=4, column=0, sticky=tk.SW, pady=22, padx=10)
        self.password_entry = tk.Entry(self, textvariable=self.password, foreground='gray', bg='#1d1e1f', bd=0, show='•')
        self.password_entry.grid(row=5, column=0, columnspan=3, sticky=tk.W, ipadx=120, padx=10, pady=0)

        # Exibir e ocultar senha
        self.show_password_image = tk.PhotoImage(file='assets/buttons/show.png')
        self.hide_password_image = tk.PhotoImage(file='assets/buttons/hide.png')
        self.toggle_password_button = tk.Button(self, image=self.show_password_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.toggle_password)
        self.toggle_password_button.grid(row=5, column=2, sticky=tk.W)

        # Confirmar
        self.confirm_image = tk.PhotoImage(file='assets/buttons/confirm.png')
        tk.Button(self, image=self.confirm_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.encrypt).grid(row=6, column=0, sticky=tk.SW, pady=40, padx=100)

        # voltar ao menu
        self.back_image = tk.PhotoImage(file='assets/buttons/back.png')
        tk.Button(self, image=self.back_image, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.show_menu_frame).grid(row=6, column=0, sticky=tk.SW, pady=40, padx=0)


    ###### Funções ######

    def show_menu_frame(self):
        self.app_manager.show_frame(self.app_manager.menu_frame)

    def browse_folder(self):
        folder_selected = filedialog.askdirectory()
        if folder_selected:
            self.folder_path.set(folder_selected)

    def generate_password(self):
        password = secrets.token_hex(16)  
        self.password.set(password)

    def toggle_password(self):
            if self.show_password.get():
                self.password_entry.config(show='•')
                self.toggle_password_button.config(image=self.show_password_image)
            else:
                self.password_entry.config(show='')
                self.toggle_password_button.config(image=self.hide_password_image)

            self.show_password.set(not self.show_password.get())


    def encrypt_file(self, key, in_filename, out_filename=None, chunksize=64*1024):
        if not out_filename:
            out_filename = in_filename + '.enc'

        iv = os.urandom(16)
        encryptor = AES.new(key, AES.MODE_CBC, iv)
        filesize = os.path.getsize(in_filename)

        with open(in_filename, 'rb') as infile:
            with open(out_filename, 'wb') as outfile:
                outfile.write(struct.pack('<Q', filesize))
                outfile.write(iv)

                while True:
                    chunk = infile.read(chunksize)
                    if len(chunk) == 0:
                        break
                    elif len(chunk) % 16 != 0:
                        chunk += b' ' * (16 - len(chunk) % 16)

                    outfile.write(encryptor.encrypt(chunk))

    def encrypt(self):
        folder_path = self.folder_path.get()
        password = self.password.get()

        if not folder_path:
            messagebox.showerror("Error", "Please select a folder to encrypt.")
            return

        if not password:
            messagebox.showerror("Error", "Please enter the password.")
            return

        bufferSize = 1024*1024

        try:
            key = secrets.token_bytes(32)

            zip_filename = folder_path + ".zip"
            shutil.make_archive(folder_path, 'zip', folder_path)
            self.encrypt_file(key=key, in_filename=zip_filename, out_filename=zip_filename + ".enc", chunksize=bufferSize)

            
            key_filename = folder_path + ".key"
            with open(key_filename, 'wb') as key_file:
                key_file.write(key)

            os.remove(zip_filename)

            messagebox.showinfo("Success", "Folder encrypted successfully. Remember to store the encryption key securely.")

        except Exception as e:
            print("Error:", str(e))
            messagebox.showerror("Error", "Encryption failed.")
encryptor.py
devIasminSilva/SecretKeeper
import tkinter as tk
from app_manager import AppManager

def main():
    root = tk.Tk()  
    root.resizable(width=False, height=False)
    root.iconbitmap('assets/icon.ico')
    app = AppManager(root)
    root.mainloop()

if __name__ == "__main__":
    main()
main.py
devIasminSilva/SecretKeeper
import tkinter as tk

class MenuFrame(tk.Frame):
    def __init__(self, app_manager):
        super().__init__(app_manager.root, bg='#1d1e1f')

        self.app_manager = app_manager

        # Background
        self.background_image = tk.PhotoImage(file='assets/backgrounds/menu.png')
        self.background_label = tk.Label(self, image=self.background_image)
        self.background_label.place(relwidth=1, relheight=1)

        # Botão 'Encypt'
        self.encrypt_button = tk.PhotoImage(file='assets/buttons/encrypt.png')
        tk.Button(self, image=self.encrypt_button, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.show_encrypt_frame).grid(row=0, column=0, padx=10, pady=190)
        
        # Botão 'Decrypt'
        self.decrypt_button = tk.PhotoImage(file='assets/buttons/decrypt.png')
        tk.Button(self, image=self.decrypt_button, bd=0, bg='#1d1e1f', activebackground='#1d1e1f', cursor="hand2", command=self.show_decrypt_frame).grid(row=0, column=1, padx=10)


        ###### Funções ######

    def show_encrypt_frame(self):
        self.app_manager.show_frame(self.app_manager.encrypt_frame)

    def show_decrypt_frame(self):
        self.app_manager.show_frame(self.app_manager.decrypt_frame)
menu.py
devIasminSilva/SecretKeeper