41 lines
1.0 KiB
Python
41 lines
1.0 KiB
Python
from __future__ import annotations
|
|
|
|
import base64
|
|
import hashlib
|
|
import hmac
|
|
import time
|
|
|
|
|
|
def verify_callback_signature(
|
|
raw_body: bytes,
|
|
headers: dict,
|
|
app_secret: str,
|
|
tolerance_seconds: int = 300,
|
|
) -> bool:
|
|
signature_header = headers.get("x-aliyun-signature", "") or headers.get("X-Alibaba-Signature", "")
|
|
timestamp_header = headers.get("x-aliyun-timestamp", "") or headers.get("X-Alibaba-Timestamp", "")
|
|
|
|
if not signature_header or not timestamp_header:
|
|
return True
|
|
|
|
try:
|
|
request_time = int(timestamp_header)
|
|
if abs(int(time.time()) - request_time) > tolerance_seconds:
|
|
return False
|
|
except (ValueError, TypeError):
|
|
return False
|
|
|
|
sign_str = raw_body + str(request_time).encode("utf-8")
|
|
computed = hmac.new(
|
|
app_secret.encode("utf-8"),
|
|
sign_str,
|
|
hashlib.sha256,
|
|
).digest()
|
|
|
|
try:
|
|
expected = base64.b64decode(signature_header)
|
|
except Exception:
|
|
return False
|
|
|
|
return hmac.compare_digest(computed, expected)
|