Baseline md2vk: docs, audit log, docker 8420, openspec, deploy

This commit is contained in:
estorozhenko
2026-09-18 22:05:01 +00:00
commit 09e960a3a9
39 changed files with 3716 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
"""Безопасность: шифрование токенов, генерация 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)