About Signature
Generation Process
1 Build signature content: Encrypt timestamp method requestPath and body using HMAC SHA256 with SecretKey then encode using Base64
2 Sorting rules:
- Parameters in
requestPathand content inbodyshould follow the same sorting rule - Sorting order:
int→float/double→string→list & object - Data of the same type are sorted lexicographically
listandobjectare sorted based on their positions in the sequence - Consistent recursive sorting rule for nested structures
- Empty values (such as
nulland'') as well as empty arrays[]and empty dictionaries{}are excluded from the signature
3 Example:
- Input example:
{{“x”: 1 “y”: 2} 1 3 2 -4 11 “xxxxx” “yyyy” “jscx” 0 “sss” {“z”: 2 “x”: 1 “a”: “”}} - After sorting:
{-4 0 1 2 3 11 “jscx” “sss” “xxxxx” “yyyy” {“x”: 1 “y”: 2} {“x”: 1 “z”: 2}}
Important Notes
- Ensure data sorting during transmission is independent of the content
- If both
pathandbodycontain parameters sort them separately and concatenate astimestamp + method + requestPath + body
Example Signature
timestamp = 1538054050234method = GETrequestPath = /api/v1/crypto/order?order_no=sdf23?token=ETHbodyis empty- Signature content:
1538054050234 + GET + /api/v1/crypto/order?token=ETH?order_no=sdf23
Timestamp Format
timestampuses ISO formatted Unix timestamp (milliseconds) eg1538054050231
Other Instructions
methodis the request method and must be uppercaserequestPathis case-sensitive if ending with/it should still be retainedbodyis the request body string it can be omitted if there is no body- Any empty parameters are filtered out and not included in the signature
- Use HMAC SHA256 and
SecretKeyto sign the hash string finally encoded in Base64
```python
import base64
import hmac
import json
import requests
from datetime import datetime
from typing import Dict Any List Union Type
# Signature
class SignatureUtility:
def generate_signature(self secret_key: str message: str) -> str:
Generate the HMAC SHA256 signature for a given message
signature = hmacnew(secret_keyencode() messageencode() digestmod=sha256)digest()
return base64b64encode(signature)decode()
def verify_signature(self secret_key: str message: str received_signature: str) -> bool:
Verify the received signature against the computed one
computed_signature = selfgenerate_signature(secret_key message)
return hmaccompare_digest(computed_signature received_signature)
def clean_and_sort_dict(self data: Union[Dict[Any Union[Dict Any]] List[Union[Dict Any]]]) -> Union[Dict[Any Union[Dict Any]] List[Union[Dict Any]]]:
if isinstance(data dict):
sorted_dict = {}
for key value in sorted(dataitems()):
if isinstance(value (dict list)):
value = selfclean_and_sort_dict(value)
# Checking for non-empty values including non-empty lists and non-empty dictionaries
if value or value == 0:
sorted_dict[key] = value
return sorted_dict if sorted_dict else None # Return None if the dictionary is empty
elif isinstance(data list):
int_list = sorted([item for item in data if isinstance(item int)])
float_list = sorted([item for item in data if isinstance(item float)])
str_list = sorted([item for item in data if isinstance(item str)])
complex_data_types = [item for item in data if isinstance(item (dict list))]
sorted_complex_data = [selfclean_and_sort_dict(item) for item in complex_data_types]
sorted_complex_data = [item for item in sorted_complex_data if item] # Filter out None values
result = int_li
Updated about 3 hours ago