# -*- coding: utf-8 -*- """密码哈希与令牌生成(仅用标准库,无额外依赖)。 - 密码:加盐 SHA-256,与 PineAgents 主后端历史实现一致(salted SHA-256)。 - 令牌:不透明随机串,存于 tokens.json。下一阶段换成数据库时, 该随机串即 ``tokens.token`` 列的主键值,语义与 JWT/会话表一致。 """ from __future__ import annotations import hashlib import hmac import secrets def hash_password(password: str, salt: str | None = None) -> tuple[str, str]: """计算 (hash_hex, salt_hex)。未提供 salt 时自动生成随机盐。""" if salt is None: salt = secrets.token_hex(16) digest = hashlib.sha256((salt + password).encode("utf-8")).hexdigest() return digest, salt def verify_password(password: str, stored_hash: str, salt: str) -> bool: """常数时间比较,防时序侧信道。""" digest, _ = hash_password(password, salt) return hmac.compare_digest(digest, stored_hash) def generate_token() -> str: """生成不透明访问令牌(URL-safe,约 64 字符)。""" return secrets.token_urlsafe(48)