""" Flare – Fernet şifreleme yardımcıları - encrypt(): düz string → "enc:" - decrypt(): enc: → düz string (veya enc: yoksa aynen döner) Anahtar: FLARE_TOKEN_KEY (32-bayt, base64, URL-safe) CLI Kullanımı: python encryption_utils.py enc "şifrelenecek metin" [--key KEY] python encryption_utils.py dec "enc:..." [--key KEY] """ import os import sys import argparse from typing import Optional from cryptography.fernet import Fernet, InvalidToken try: from .logger import log_error, log_warning except ImportError: # Fallback to simple print def log_error(msg, error=None): print(f"ERROR: {msg}", file=sys.stderr) if error: print(f"Details: {error}", file=sys.stderr) def log_warning(msg): print(f"WARNING: {msg}", file=sys.stderr) _ENV_KEY = "FLARE_TOKEN_KEY" def _get_key() -> Fernet: """Get encryption key with better error messages""" # Direkt environment variable kullan key = os.getenv(_ENV_KEY) # .env dosyasından yüklemeyi dene if not key: try: from dotenv import load_dotenv load_dotenv() key = os.getenv(_ENV_KEY) except ImportError: pass if not key: error_msg = ( f"{_ENV_KEY} ortam değişkeni tanımlanmadı. " f"Lütfen 32-byte base64 key oluşturun: python generate_key.py" ) log_error(error_msg) raise RuntimeError(error_msg) # Key formatını kontrol et try: return Fernet(key.encode()) except Exception as e: error_msg = ( f"{_ENV_KEY} geçersiz format. " f"32-byte base64 URL-safe key olmalı. " f"Yeni key için: python generate_key.py" ) log_error(error_msg, error=str(e)) raise RuntimeError(error_msg) def encrypt(plain: str, key: Optional[str] = None) -> str: """düz string → enc:...""" if not plain: log_warning("Empty string passed to encrypt") return "" try: if key: f = Fernet(key.encode()) else: f = _get_key() encrypted = f.encrypt(plain.encode()).decode() return "enc:" + encrypted except Exception as e: log_error("Encryption failed", error=str(e)) raise def decrypt(value: Optional[str], key: Optional[str] = None) -> Optional[str]: """enc:... ise çözer, değilse aynen döndürür""" if value is None or not isinstance(value, str): return value if not value.startswith("enc:"): return value token = value.split("enc:", 1)[1] try: if key: f = Fernet(key.encode()) else: f = _get_key() decrypted = f.decrypt(token.encode()).decode() return decrypted except InvalidToken: error_msg = ( "Şifre çözme başarısız. Muhtemel sebepler:\n" "1. FLARE_TOKEN_KEY değişti\n" "2. Şifreli veri bozuldu\n" "3. Farklı bir key ile şifrelendi" ) log_error(error_msg) raise RuntimeError(error_msg) except Exception as e: log_error("Decryption error", error=str(e)) raise def generate_key() -> str: """Generate a new Fernet encryption key""" return Fernet.generate_key().decode() def main(): """CLI entry point""" parser = argparse.ArgumentParser( description="Fernet encryption/decryption utility", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Generate a new key python encryption_utils.py keygen # Save generated key to .env file python encryption_utils.py keygen >> .env # Then edit .env to add: FLARE_TOKEN_KEY= # Encrypt with environment key python encryption_utils.py enc "secret message" # Encrypt with custom key python encryption_utils.py enc "secret message" --key "your-32-byte-base64-key" # Decrypt python encryption_utils.py dec "enc:gAAAAABh..." # Decrypt with custom key python encryption_utils.py dec "enc:gAAAAABh..." --key "your-32-byte-base64-key" """ ) parser.add_argument( "command", choices=["enc", "dec", "keygen"], help="Command to execute: 'enc' for encrypt, 'dec' for decrypt, 'keygen' to generate new key" ) parser.add_argument( "text", nargs="?", help="Text to encrypt or decrypt (not needed for keygen)" ) parser.add_argument( "--key", help="Optional Fernet key (32-byte base64). If not provided, uses FLARE_TOKEN_KEY env var" ) args = parser.parse_args() try: if args.command == "keygen": key = generate_key() print(key) elif args.command == "enc": if not args.text: parser.error("Text is required for encryption") result = encrypt(args.text, args.key) print(result) else: # dec if not args.text: parser.error("Text is required for decryption") result = decrypt(args.text, args.key) print(result) except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main()