Files
gsfdc/server/app/core/crypto.py
T

44 lines
1.5 KiB
Python

import base64
import json
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from fastapi import HTTPException, status
from app.core.config import get_settings
def _key() -> bytes:
settings = get_settings()
raw = settings.api_payload_aes_key.strip()
if not raw:
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="接口加密未配置")
try:
key = base64.b64decode(raw)
except Exception:
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="接口加密未配置")
if len(key) not in {16, 24, 32}:
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="接口加密未配置")
return key
def encrypt_json(payload: dict | list) -> dict:
nonce = os.urandom(12)
plain = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode()
ciphertext = AESGCM(_key()).encrypt(nonce, plain, None)
return {"data": base64.b64encode(nonce + ciphertext).decode()}
def decrypt_json(envelope: dict) -> dict | list:
token = envelope.get("data")
if not isinstance(token, str):
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="加密报文格式不正确")
try:
raw = base64.b64decode(token)
plain = AESGCM(_key()).decrypt(raw[:12], raw[12:], None)
return json.loads(plain)
except HTTPException:
raise
except Exception:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="加密报文无法解密")