GigaProjects

← Back to NanoLock

nanolock.py

import base64
import os
import getpass
import sys
from cryptography.fernet import Fernet, InvalidToken
from argon2.low_level import hash_secret_raw, Type


def get_key(password, salt):
    """Derive a Fernet key using Argon2id"""
    key = hash_secret_raw(
        secret=password,
        salt=salt,
        time_cost=4,          # 4 passes over memory
        memory_cost=1048576,  # 1 GiB – adjust down to 524288 (512 MiB), 262144 (256 MiB) or even to 65536 (64 MiB) on weak devices
        parallelism=4,        # use 4 cores
        hash_len=32,
        type=Type.ID,         # Argon2id = most secure variant
    )
    return base64.urlsafe_b64encode(key)


def main():
    print(r"""
 _   _                   _               _    
| \ | | __ _ _ __   ___ | |    ___   ___| | __
|  \| |/ _` | '_ \ / _ \| |   / _ \ / __| |/ /
| |\  | (_| | | | | (_) | |__| (_) | (__|   < 
|_| \_|\__,_|_| |_|\___/|_____\___/ \___|_|\_\                                               
    """)
    mode = input("Select -> (E)ncrypt or (D)ecrypt: ").strip().upper()

    if mode not in ["E", "D"]:
        print("Invalid mode.")
        return

    password = getpass.getpass("Enter password: ").encode()
    if not password:
        print("Password cannot be empty.")
        return

    if mode == "E":
        confirm = getpass.getpass("Confirm password: ").encode()
        if password != confirm:
            print("Passwords do not match!")
            return

        text = input("Enter text to encrypt: ").encode()

        salt = os.urandom(16)
        key = get_key(password, salt)
        token = Fernet(key).encrypt(text)

        result = base64.urlsafe_b64encode(salt + token)
        print("\nENCRYPTED OUTPUT:")
        print(result.decode())

    elif mode == "D":
        encrypted_input = input("Paste encrypted text: ").strip()

        try:
            decoded_data = base64.urlsafe_b64decode(encrypted_input)
            if len(decoded_data) <= 16:
                raise ValueError("Invalid data")

            salt, token = decoded_data[:16], decoded_data[16:]
            key = get_key(password, salt)

            original_text = Fernet(key).decrypt(token).decode()
            print("\nDECRYPTED TEXT:")
            print(original_text)

        except InvalidToken:
            print("\nERROR: Wrong password or corrupted data.")
        except Exception as e:
            print(f"\nERROR: Invalid input – {e}")


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\nBye!")
        sys.exit(0)

Run this code