"""Безопасность: шифрование токенов, генерация API-ключей.""" from __future__ import annotations import hashlib import hmac import secrets from typing import Optional from cryptography.fernet import Fernet, InvalidToken from app.config import settings def get_fernet() -> Fernet: """Создаёт Fernet-инстанс из ключа в settings.""" return Fernet(settings.fernet_key) def encrypt_token(token: str) -> str: """Шифрует VK-токен. Возвращает base64-строку.""" f = get_fernet() return f.encrypt(token.encode()).decode() def decrypt_token(encrypted: str) -> Optional[str]: """Расшифровывает VK-токен. Возвращает None при ошибке.""" try: f = get_fernet() return f.decrypt(encrypted.encode()).decode() except (InvalidToken, Exception): return None def generate_api_key() -> tuple[str, str]: """Генерирует пару (api_key, api_key_hash). api_key — то, что отдаётся пользователю (md2vk_xxx...) api_key_hash — SHA-256 хеш, хранится в БД. """ raw = secrets.token_hex(32) api_key = f"md2vk_{raw}" api_key_hash = hashlib.sha256(api_key.encode()).hexdigest() return api_key, api_key_hash def verify_api_key(api_key: str, api_key_hash: str) -> bool: """Проверяет API-ключ по хранимому хешу (constant-time).""" computed = hashlib.sha256(api_key.encode()).hexdigest() return hmac.compare_digest(computed, api_key_hash)