| 12345678910111213141516171819202122232425262728293031323334353637383940 |
- import hashlib
- import hmac
- import time
- from typing import Dict, Any
- class SignatureService:
- @staticmethod
- def verify_signature(secret: str, params: Dict[str, Any], sign: str, tolerance: int = 300) -> bool:
- """
- Verifies the signature of the request.
-
- Algorithm:
- 1. Check timestamp freshness (tolerance seconds).
- 2. Sort keys alphabetically.
- 3. Concatenate key=value&key=value...
- 4. Calculate HMAC-SHA256 with secret.
- 5. Compare with sign.
- """
- # 1. Check timestamp
- ts = int(params.get("timestamp", 0))
- now = int(time.time())
- if abs(now - ts) > tolerance:
- return False
- # 2. Prepare string to sign
- # Filter out 'sign' itself and empty values if any? usually we sign all except signature
- data_to_sign = {k: v for k, v in params.items() if k != "sign"}
-
- sorted_keys = sorted(data_to_sign.keys())
- query_string = "&".join([f"{k}={data_to_sign[k]}" for k in sorted_keys])
-
- # 3. Calculate HMAC
- calculated_sign = hmac.new(
- secret.encode('utf-8'),
- query_string.encode('utf-8'),
- hashlib.sha256
- ).hexdigest()
-
- return hmac.compare_digest(calculated_sign, sign)
|