"""JWT 鉴权 + 店铺凭证 AES-GCM 加解密。""" from __future__ import annotations import base64 import hashlib import os from datetime import datetime, timedelta, timezone import jwt from config import get_settings # ── JWT ── def create_access_token(subject: str = "app") -> tuple[str, int]: """签发 JWT。返回 (token, 过期 epoch 秒)。""" settings = get_settings() expires = datetime.now(timezone.utc) + timedelta(minutes=settings.jwt_expire_minutes) payload = {"sub": subject, "exp": expires} token = jwt.encode(payload, settings.secret_key, algorithm="HS256") return token, int(expires.timestamp()) def decode_token(token: str) -> dict: """校验并解析 JWT;失败抛 jwt.PyJWTError。""" settings = get_settings() return jwt.decode(token, settings.secret_key, algorithms=["HS256"]) # ── AES-GCM 店铺凭证加密 ── def _derive_key() -> bytes: settings = get_settings() return hashlib.sha256(settings.secret_key.encode("utf-8")).digest() def encrypt_secret(plaintext: str) -> str: """AES-GCM 加密,返回 base64(nonce + ciphertext + tag)。""" from cryptography.hazmat.primitives.ciphers.aead import AESGCM key = _derive_key() nonce = os.urandom(12) aesgcm = AESGCM(key) ct = aesgcm.encrypt(nonce, plaintext.encode("utf-8"), None) return base64.b64encode(nonce + ct).decode("ascii") def decrypt_secret(ciphertext: str) -> str: from cryptography.hazmat.primitives.ciphers.aead import AESGCM key = _derive_key() raw = base64.b64decode(ciphertext.encode("ascii")) nonce, ct = raw[:12], raw[12:] aesgcm = AESGCM(key) return aesgcm.decrypt(nonce, ct, None).decode("utf-8")