Files

183 lines
5.5 KiB
Python
Raw Permalink Normal View History

2026-05-31 18:46:06 +08:00
"""
CryptZ Ultimate v5 — CLI Module
Usage:
cryptz.py encrypt -p PASSWORD -o OUTPUT file1 file2 ...
cryptz.py decrypt -p PASSWORD -o OUTPUT_DIR archive.cryptz
cryptz.py verify -p PASSWORD archive.cryptz
"""
import argparse
import sys
import os
import getpass
# Force UTF-8 stdout on Windows
if sys.platform == "win32":
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
from crypto_engine import (
EncryptOptions, decrypt, encrypt, verify_integrity,
check_password_strength, EXTENSION,
)
def _progress(value: float, msg: str):
bar_len = 30
filled = int(bar_len * value)
bar = "#" * filled + "-" * (bar_len - filled)
line = " [{}] {:5.1f}% {:<40}".format(bar, value * 100, msg)
sys.stdout.write("\r" + line)
sys.stdout.flush()
if value >= 1.0:
print()
def cmd_encrypt(args):
password = args.password or getpass.getpass("Password: ")
score, label = check_password_strength(password)
if score < 2:
print("[!] Warning: password is {}. Consider strengthening it.".format(label.lower()))
if not args.files:
print("[ERROR] Specify files to encrypt.")
sys.exit(1)
for f in args.files:
if not os.path.exists(f):
print("[ERROR] File not found: {}".format(f))
sys.exit(1)
output = args.output or (os.path.splitext(args.files[0])[0] + EXTENSION)
options = EncryptOptions(
password=password,
files=args.files,
output_path=output,
use_2fa=args.twofa,
max_attempts=args.max_attempts,
hardware_key_path=args.key_file,
secure_delete=args.shred,
compress=not args.no_compress,
progress_callback=_progress,
)
if args.twofa:
import pyotp
options.otp_secret = pyotp.random_base32()
print("")
print("[2FA] Secret: {}".format(options.otp_secret))
uri = pyotp.TOTP(options.otp_secret).provisioning_uri("CryptZ", "CryptZ CLI")
print("[2FA] URI: {}".format(uri))
print("[2FA] Save this secret! It will be required for decryption.")
print("")
try:
result = encrypt(options)
print("")
print("[OK] Archive created: {}".format(result))
except Exception as e:
print("")
print("[ERROR] {}".format(e))
sys.exit(1)
def cmd_decrypt(args):
password = args.password or getpass.getpass("Password: ")
if not os.path.exists(args.archive):
print("[ERROR] File not found: {}".format(args.archive))
sys.exit(1)
output_dir = args.output or "."
os.makedirs(output_dir, exist_ok=True)
result = decrypt(
file_path=args.archive,
password=password,
output_dir=output_dir,
hardware_key_path=args.key_file,
otp_code=args.otp,
progress_callback=_progress,
)
if result.needs_2fa and not args.otp:
print("")
otp = input("[2FA] Enter TOTP code: ").strip()
result = decrypt(
file_path=args.archive,
password=password,
output_dir=output_dir,
hardware_key_path=args.key_file,
otp_code=otp,
progress_callback=_progress,
)
print("")
if result.success:
print("[OK] {}".format(result.message))
else:
print("[FAIL] {}".format(result.message))
sys.exit(1)
def cmd_verify(args):
password = args.password or getpass.getpass("Password: ")
if not os.path.exists(args.archive):
print("[ERROR] File not found: {}".format(args.archive))
sys.exit(1)
ok, msg = verify_integrity(args.archive, password, args.key_file)
if ok:
print("[OK] {}".format(msg))
else:
print("[FAIL] {}".format(msg))
sys.exit(1)
def cli_main():
parser = argparse.ArgumentParser(
prog="cryptz",
description="CryptZ Ultimate v5 -- AES-256-GCM CLI Archiver",
)
sub = parser.add_subparsers(dest="command", required=True)
# encrypt
enc = sub.add_parser("encrypt", help="Encrypt files")
enc.add_argument("files", nargs="+", help="Files to encrypt")
enc.add_argument("-p", "--password", help="Password (or will be prompted)")
enc.add_argument("-o", "--output", help="Output file")
enc.add_argument("-k", "--key-file", help="Key file")
enc.add_argument("--2fa", dest="twofa", action="store_true", help="Enable 2FA")
enc.add_argument("--shred", action="store_true", help="Securely delete originals")
enc.add_argument("--no-compress", action="store_true", help="Disable compression")
enc.add_argument("--max-attempts", type=int, default=5, help="Max attempts (default: 5)")
# decrypt
dec = sub.add_parser("decrypt", help="Decrypt archive")
dec.add_argument("archive", help=".cryptz file")
dec.add_argument("-p", "--password", help="Password")
dec.add_argument("-o", "--output", help="Output directory")
dec.add_argument("-k", "--key-file", help="Key file")
dec.add_argument("--otp", help="2FA code")
# verify
ver = sub.add_parser("verify", help="Verify archive integrity")
ver.add_argument("archive", help=".cryptz file")
ver.add_argument("-p", "--password", help="Password")
ver.add_argument("-k", "--key-file", help="Key file")
args = parser.parse_args()
if args.command == "encrypt":
cmd_encrypt(args)
elif args.command == "decrypt":
cmd_decrypt(args)
elif args.command == "verify":
cmd_verify(args)
if __name__ == "__main__":
cli_main()