commit 0d62ef4ba1bc756b3ecdcda3aaf288eb31e42c67 Author: The-Tysonator Date: Sat Apr 29 09:15:08 2023 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc6664a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_STORE +venv/ \ No newline at end of file diff --git a/TheLocker.py b/TheLocker.py new file mode 100755 index 0000000..19221b6 --- /dev/null +++ b/TheLocker.py @@ -0,0 +1,243 @@ +# Imports +import pyfiglet, os, base64 +from cryptography.fernet import Fernet + + +# Terminal Text Class +class TerminalText(): + # Options + COLOR_MAIN = "\033[94m" + COLOR_PROCESSING = "\033[93m" + COLOR_SUCCESS = "\033[92m" + COLOR_ERROR = "\033[91m" + COLOR_END = "\033[0m" + + +# Print Title +def printTitle(): + # Start Color + print(TerminalText.COLOR_MAIN) + # Text + pyfiglet.print_figlet("The Locker") + print(" by Tylan Tyson", end = "") + # End Color + print(TerminalText.COLOR_END) + + +# Print Menu +def printMenu(): + # Color + print(TerminalText.COLOR_MAIN) + # Text + print("--------------------------------------------------") + print("| Option 1: Encrypt |") + print("| Option 2: Decrypt |") + print("| Option 3: Exit |") + print("--------------------------------------------------") + # Input + option = input(" Option: ") + # End Color + print(TerminalText.COLOR_END) + # Return + return option + + +# Generate Key +def generateKey(): + # Get Valid Password + password = "" + password_valid = False + while not password_valid: + password = input("| Choose Password: ") + if len(password) >= 1 and len(password) <= 32: + password_valid = True + else: + print(TerminalText.COLOR_ERROR, "ERROR - Password must be between 1 and 32 characters long.", TerminalText.COLOR_PROCESSING) + print(TerminalText.COLOR_SUCCESS, "SUCCESS - Password accepted.", TerminalText.COLOR_PROCESSING) + # Adjust Length + counter = 0 + while len(password) != 32: + character = password[counter] + password += character + counter += 1 + # Create Key + password = bytes(password.encode()) + key = base64.b64encode(password) + return key + + +# Check Path +def checkPath(): + # Get Valid Input + path = None + path_valid = False + while not path_valid: + path = input("| Choose Path: ") + if os.path.exists(path): + if os.path.isdir(path): + path_valid = True + else: + print(TerminalText.COLOR_ERROR, "ERROR - Path is not a directory.", TerminalText.COLOR_PROCESSING) + else: + print(TerminalText.COLOR_ERROR, "ERROR - Path does not exist.", TerminalText.COLOR_PROCESSING) + print(TerminalText.COLOR_SUCCESS, "SUCCESS - Path accepted.", TerminalText.COLOR_PROCESSING) + # Return Path + return path + + +# Encrypt +def encrypt(key, directory_path): + # Fernet Object + fernet = Fernet(key) + # Loop Through Files + counter = 0 + for root, directories, files in os.walk(directory_path): + for file in files: + # Avoid Errors + try: + # File Information + file_path = os.path.join(root, file) + with open(file_path, "rb") as file: + file_data = file.read() + # File Path To Encrypt + file_path_to_encrypt = file_path.split(os.sep) + # Remove Empty Space + for directory in file_path_to_encrypt: + if directory == "": + file_path_to_encrypt.remove(directory) + # Find Root Index + root_index = None + for directory_index, directory in enumerate(file_path_to_encrypt): + if directory == directory_path.split(os.sep)[-1]: + root_index = directory_index + if root_index != None: + break + # Remove Items Upto Root Index + if root_index > 0: + for i in range(root_index + 1): + file_path_to_encrypt.pop(0) + # Encrypt + with open(os.path.join(directory_path, f"THELOCKERFILE_{counter}.txt"), "w") as file: + file.write(f"{str(fernet.encrypt(str(file_path_to_encrypt).encode()))}\n{str(fernet.encrypt(file_data))}") + # Remove Encrypted File + os.remove(file_path) + # Display + print("Encrypting: ", file_path, TerminalText.COLOR_SUCCESS, "- SUCCESS", TerminalText.COLOR_PROCESSING) + except: + print("Encrypting: ", file_path, TerminalText.COLOR_ERROR, "- ERROR", TerminalText.COLOR_PROCESSING) + # Counter + counter += 1 + # Remove Folders + while [i.path for i in os.scandir(directory_path) if i.is_dir()] != []: + for root, directories, files in os.walk(directory_path): + for directory in directories: + try: + os.rmdir(os.path.join(root, directory)) + except: + pass + # Title + printTitle() + + +# Decrypt +def decrypt(key, directory_path): + # Fernet Object + fernet = Fernet(key) + # Loop Through Files + for root, directories, files in os.walk(directory_path): + for file in files: + # Avoid Errors + try: + # Filter Locker Files + if "THELOCKERFILE" in file: + # Read File + with open (os.path.join(directory_path, file)) as file1: + file_contents = file1.read() + file_contents = file_contents.split("\n") + # File Path + file_path = file_contents[0] + file_path = file_path[2:] + file_path = file_path[:len(file_path) - 1] + file_path = str(fernet.decrypt(bytes(file_path.encode()))) + decrypted_path = file_path + file_path = file_path[2:] + file_path = file_path[:len(file_path) - 1] + file_path = eval(file_path) + # Get Required Folders + required_folders = [] + get_folders = file_path + get_folders.pop(-1) + for file3 in get_folders: + required_folders.append(file3) + # Create Required Folders + current_folder = None + for folder in required_folders: + if current_folder != None: + current_folder = os.path.join(current_folder, folder) + else: + current_folder = os.path.join(directory_path, folder) + try: + os.mkdir(current_folder) + except: + pass + # Decrypt File Data + file_data = file_contents[1] + file_data = file_data[2:] + file_data = file_data[:len(file_data) - 1] + file_data = fernet.decrypt(bytes(file_data.encode())) + # File Path To Write To + decrypted_path = decrypted_path[2:] + decrypted_path = decrypted_path[:len(decrypted_path) - 1] + decrypted_path = eval(decrypted_path) + write_path = None + for i in decrypted_path: + if write_path == None: + write_path = i + else: + write_path = os.path.join(write_path, i) + # Write File + with open(os.path.join(directory_path, write_path), "wb") as writetofile: + writetofile.write(file_data) + # Remove LOCKERFILE + os.remove(os.path.join(directory_path, file)) + # Display + print("DECRYPTING: ", write_path, TerminalText.COLOR_SUCCESS, "- SUCCESS", TerminalText.COLOR_PROCESSING) + except: + print("DECRYPTING: ", write_path, TerminalText.COLOR_ERROR, "- ERROR", TerminalText.COLOR_PROCESSING) + # Title + printTitle() + + +# Print Title +printTitle() +print() + + +# Program Loop +while True: + # Print Menu + option = printMenu() + # Options + if option == "1": + print(TerminalText.COLOR_PROCESSING) + key = generateKey() + print() + path = checkPath() + print() + encrypt(key, path) + print(TerminalText.COLOR_END) + elif option == "2": + print(TerminalText.COLOR_PROCESSING) + key = generateKey() + print() + path = checkPath() + print() + decrypt(key, path) + print(TerminalText.COLOR_END) + elif option == "3": + exit() + # Invallid Option + else: + print(TerminalText.COLOR_ERROR) + print(" Invallid Option") + print(TerminalText.COLOR_END) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c7e1d23 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +cffi==1.15.1 +cryptography==40.0.2 +pycparser==2.21 +pyfiglet==0.8.post1