-
-
Save Apocryphon-X/6b628d4f5b69df01395165281291986e to your computer and use it in GitHub Desktop.
Symmetric encryption utility. (Wrapper of GPG - For personal use)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| # Copyright (c) 2022 @Apocryphon (Dante Mendoza Leyva). | |
| # All rights reserved. | |
| import click | |
| import subprocess | |
| import pathlib | |
| import shutil | |
| import sys | |
| import zipfile | |
| import pwinput | |
| import blessed | |
| term = blessed.Terminal() | |
| @click.command(help="Encrypts the given file (or directory) using OpenPGP.") | |
| @click.argument("TARGET-PATHS", nargs=-1) | |
| @click.option("--version", "-v", help="Shows the encrypter version.", is_flag=True) | |
| @click.option( | |
| "--same-passphrase", | |
| "-s", | |
| help="Use the same passphrase for every file.", | |
| is_flag=True, | |
| ) | |
| def encrypt(target_paths, version, same_passphrase): | |
| if version: | |
| sys.stderr.write("lock: Version 3.0\n") | |
| sys.stderr.write(f"{'-' * 25}\n") | |
| subprocess.run(["gpg", "--version"]) | |
| return | |
| if len(target_paths) == 0: | |
| sys.stderr.write("lock: Nothing to do.\n") | |
| return | |
| passphrase = "" | |
| if same_passphrase: | |
| p1 = "-" | |
| p2 = "+" | |
| while p1 != p2: | |
| p1 = pwinput.pwinput(prompt="? Enter passphrase: ", mask="•") | |
| p2 = pwinput.pwinput(prompt="? Please re-enter this passphrase: ", mask="•") | |
| if p1 != p2: | |
| sys.stderr.write(f"\nlock: {term.red('Does not match - try again.')}\n") | |
| print(f"{'-' * 40}") | |
| passphrase = p1 | |
| for target_path in target_paths: | |
| target_path = pathlib.Path(target_path) | |
| result_path = f"{target_path.resolve()}" | |
| is_dir_cache = target_path.is_dir() | |
| if is_dir_cache: | |
| with zipfile.ZipFile(f"{result_path}.lock", "w") as zip_obj: | |
| for file in target_path.glob("**/*"): | |
| file_path = file.parent.joinpath(file.name) | |
| relative_path = file_path.relative_to(target_path.parent) | |
| sys.stderr.write( | |
| f"lock: {term.green('[+]')} {term.yellow('Adding:')} {term.gray(str(file_path.resolve()))}\n" | |
| ) | |
| zip_obj.write(file_path, relative_path, zipfile.ZIP_DEFLATED) | |
| result_path += ".lock" | |
| command = ["gpg", "--no-symkey-cache", "-c"] | |
| if same_passphrase: | |
| command += ["--batch", "--yes"] | |
| command += ["--passphrase", passphrase] | |
| command.append(result_path) | |
| result = subprocess.run(command, capture_output=True) | |
| logs = result.stderr.decode("ascii") | |
| # Logs formatting | |
| logs = logs.replace( | |
| "No such file or directory", term.red("No such file or directory") | |
| ) | |
| logs = logs.replace("Invalid passphrase", term.red("Invalid passphrase")) | |
| if len(logs) > 0: | |
| sys.stderr.write(f"{logs.strip()}\n") | |
| if "failed" in logs or "can't open" in logs: | |
| if is_dir_cache: | |
| zip_path = pathlib.Path(result_path) | |
| zip_path.unlink(missing_ok=True) | |
| continue | |
| gpg_file_path = pathlib.Path(f"{result_path}.gpg") | |
| if is_dir_cache: | |
| shutil.rmtree(target_path) | |
| gpg_file_path.replace(result_path) | |
| sys.stderr.write( | |
| f"lock: Symmetric encryption of '{target_path}' {term.green('ended succesfully.')}\n" | |
| ) | |
| if __name__ == "__main__": | |
| encrypt() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| # Copyright (c) 2022 Apocryphon-X (Dante Mendoza Leyva). | |
| # All rights reserved. | |
| import click | |
| import subprocess | |
| import pathlib | |
| import shutil | |
| import zipfile | |
| import sys | |
| import pwinput | |
| import blessed | |
| term = blessed.Terminal() | |
| @click.command(help="Decrypts the given file (or directory) using OpenPGP.") | |
| @click.argument("TARGET-PATHS", nargs=-1) | |
| @click.option("--version", "-v", help="Shows the decrypter version.", is_flag=True) | |
| @click.option( | |
| "--same-passphrase", | |
| "-s", | |
| help="Use the same passphrase for every file.", | |
| is_flag=True, | |
| ) | |
| def decrypt(target_paths, version, same_passphrase): | |
| if version: | |
| sys.stderr.write("unlock: Version 3.0\n") | |
| sys.stderr.write(f"{'-' * 25}\n") | |
| subprocess.run(["gpg", "--version"]) | |
| return | |
| if len(target_paths) == 0: | |
| sys.stderr.write("unlock: Nothing to do.\n") | |
| return | |
| passphrase = "" | |
| if same_passphrase: | |
| p1 = "-" | |
| p2 = "+" | |
| while p1 != p2: | |
| p1 = pwinput.pwinput(prompt="? Enter passphrase: ", mask="•") | |
| p2 = pwinput.pwinput(prompt="? Please re-enter this passphrase: ", mask="•") | |
| if p1 != p2: | |
| sys.stderr.write(f"\nlock: {term.red('Does not match - try again.')}\n") | |
| passphrase = p1 | |
| sys.stderr.write(f"{'-' * 40}\n") | |
| path_counter = 0 | |
| for target_path in target_paths: | |
| target_path = pathlib.Path(target_path) | |
| command = ["gpg", "--no-symkey-cache", "-d"] | |
| if same_passphrase: | |
| command += ["--batch", "--yes"] | |
| command += ["--passphrase", passphrase] | |
| command.append(target_path.resolve()) | |
| result = subprocess.run(command, capture_output=True) | |
| logs = result.stderr.decode("ascii") | |
| # Logs formatting | |
| logs = logs.replace( | |
| "No such file or directory", term.red("No such file or directory") | |
| ) | |
| logs = logs.replace("Unknown system error", term.red("Unknown system error")) | |
| logs = logs.replace("No secret key", term.red("No secret key")) | |
| sys.stderr.write(f"{logs.strip()}\n") | |
| path_counter += 1 | |
| if "Unknown system error" in logs or "No secret key" in logs: | |
| sys.stderr.write(term.gray(f"({target_path.resolve()})\n")) | |
| if path_counter < len(target_paths): | |
| sys.stderr.write(f"\n") | |
| skip = False | |
| for error in ["failed", "can't open", "Unknown system error", "No secret key"]: | |
| if error in logs: | |
| skip = True | |
| break | |
| if skip: | |
| continue | |
| with open(target_path.resolve(), "wb") as decrypted_file: | |
| decrypted_file.write(result.stdout) | |
| if target_path.suffix == ".lock" and zipfile.is_zipfile(target_path.resolve()): | |
| with zipfile.ZipFile(target_path.resolve(), "r") as zip_ref: | |
| zip_ref.extractall(target_path.parent) | |
| target_path.unlink(missing_ok=True) | |
| sys.stderr.write( | |
| f"unlock: Symmetric decryption of '{target_path}' {term.green('ended succesfully')}.\n" | |
| ) | |
| if __name__ == "__main__": | |
| decrypt() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment