Initial commit: certgen — сервис генерации сертификатов

This commit is contained in:
apuc committed 2026-10-16 17:17:47 +03:00
commit 49bac43e16
23 files changed
+3046

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
"""Аутентификация: хеширование паролей, проверка, сессии, валидация."""
from __future__ import annotations
import hashlib
import hmac
import re
import secrets
PBKDF2_ITERATIONS = 200_000
EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
MIN_PASSWORD = 8
def hash_password(password: str, iterations: int = PBKDF2_ITERATIONS) -> str:
salt = secrets.token_bytes(16)
dk = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, iterations)
return f"pbkdf2_sha256${iterations}${salt.hex()}${dk.hex()}"
def verify_password(password: str, stored: str | None) -> bool:
if not stored:
return False
try:
algo, iters, salt_hex, digest = stored.split("$")
if algo != "pbkdf2_sha256":
return False
dk = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"),
bytes.fromhex(salt_hex), int(iters))
return hmac.compare_digest(dk.hex(), digest)
except (ValueError, AttributeError):
return False
def new_token() -> str:
return secrets.token_urlsafe(32)
def valid_email(email: str) -> bool:
email = (email or "").strip()
return bool(EMAIL_RE.match(email)) and len(email) <= 254
def validate_registration(email: str, password: str) -> str | None:
"""Вернуть текст ошибки или None, если всё хорошо."""
if not valid_email(email):
return "Некорректный email"
if len(password or "") < MIN_PASSWORD:
return f"Пароль должен быть не короче {MIN_PASSWORD} символов"
return None