Files

57 lines
1.7 KiB
Python

"""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")