请求验证
Last updated
Last updated
签名字符串 = 时间戳 + HTTP方法 + 请求路径 + 请求体func GenerateSignature(apiSecret, method, requestPath string, body interface{}) (string,string, error) {
// 生成时间戳 (RFC3339Nano格式)
timestamp := time.Now().UTC().Format(time.RFC3339Nano)
// 准备签名消息
method = strings.ToUpper(strings.TrimSpace(method))
requestPath = strings.TrimSpace(requestPath)
message := timestamp + method + requestPath
// 如果有请求体,需要处理
if body != nil {
switch v := body.(type) {
case string:
message += strings.TrimSpace(v)
case []byte:
message += strings.TrimSpace(string(v))
default:
// 如果是其他类型,转换为排序后的JSON字符串
jsonBytes, err := json.Marshal(body)
if err != nil {
return "","", fmt.Errorf("failed to marshal body: %v", err)
}
var jsonMap map[string]interface{}
if err := json.Unmarshal(jsonBytes, &jsonMap); err != nil {
return "","", fmt.Errorf("failed to unmarshal body: %v", err)
}
sortedBytes, err := json.Marshal(jsonMap)
if err != nil {
return "", "",fmt.Errorf("failed to marshal sorted body: %v", err)
}
message += string(sortedBytes)
}
}
// 使用HMAC-SHA256算法生成签名
h := hmac.New(sha256.New, []byte(apiSecret))
h.Write([]byte(message))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
return signature, timestamp,nil
}import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
public class TestSignature {
private static Map<String, Object> replaceHashMapsWithTreeMaps(Map<String, Object> map) {
Map<String, Object> treeMap = new TreeMap<>(map);
for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
if (entry.getValue() instanceof Map) {
entry.setValue(replaceHashMapsWithTreeMaps((Map<String, Object>) entry.getValue()));
} else if (entry.getValue() instanceof List) {
entry.setValue(processList((List) entry.getValue()));
}
}
return treeMap;
}
private static List processList(List list) {
List newList = new ArrayList();
for (Object item : list) {
if (item instanceof Map) {
newList.add(replaceHashMapsWithTreeMaps((Map<String, Object>) item));
} else if (item instanceof List) {
newList.add(processList((List) item));
} else {
newList.add(item);
}
}
return newList;
}
public static Map<String, Object> generateSignature(String apiSecret, String apiKey, String method, String requestPath, Object body) {
// 生成时间戳 (RFC3339Nano格式)
String timestamp = Instant.now().toString();
// 准备签名消息
method = method.toUpperCase().trim();
requestPath = requestPath.trim();
StringBuilder message = new StringBuilder()
.append(timestamp)
.append(method)
.append(requestPath);
// 如果有请求体,需要处理
if (body != null) {
try {
if (body instanceof String) {
message.append(((String) body).trim());
} else {
// 如果是对象,转换为排序后的JSON字符串
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(body);
Map<String, Object> jsonMap = mapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});
Map<String, Object> sortedMap = replaceHashMapsWithTreeMaps(jsonMap);
message.append(mapper.writeValueAsString(sortedMap));
}
} catch (Exception e) {
throw new RuntimeException("Failed to process body", e);
}
}
try {
// 使用HMAC-SHA256算法生成签名
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
hmac.init(secretKey);
byte[] hash = hmac.doFinal(message.toString().getBytes(StandardCharsets.UTF_8));
String signature = Base64.getEncoder().encodeToString(hash);
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("signature", signature);
result.put("timestamp", timestamp);
Map<String, String> headers = new HashMap<>();
headers.put("AVE-ACCESS-SIGN", signature);
headers.put("AVE-ACCESS-TIMESTAMP", timestamp);
headers.put("AVE-ACCESS-KEY", apiKey);
result.put("headers", headers);
Map<String, String> debug = new HashMap<>();
debug.put("message", message.toString());
debug.put("method", method);
debug.put("request_path", requestPath);
result.put("debug", debug);
return result;
} catch (Exception e) {
throw new RuntimeException("Failed to generate signature", e);
}
}
}import hmac
import hashlib
import json
import base64
from datetime import datetime
from typing import Union, Dict, Any
def generate_signature(api_secret: str, method: str, request_path: str, body: Union[str, dict, None] = None) -> Dict[str, Any]:
"""
生成API请求签名
Args:
api_secret: API密钥
method: 请求方法 (GET, POST, PUT等)
request_path: 请求路径
body: 请求体 (可选,字符串或字典)
Returns:
包含签名和时间戳的字典
"""
# 生成时间戳 (RFC3339Nano格式)
timestamp = datetime.utcnow().isoformat() + 'Z'
# 准备签名消息
method = method.upper().strip() # 确保方法是大写且没有空格
request_path = request_path.strip() # 移除路径中可能的空格
message = timestamp + method + request_path
# 如果有请求体,需要处理
if body:
if isinstance(body, dict):
# 如果body是字典,转换为排序后的JSON字符串,确保没有空格
message += json.dumps(body, sort_keys=True, separators=(',', ':'))
else:
# 如果是字符串,确保移除可能的空格
message += str(body).strip()
print(f"Debug - Message to sign: {message}") # 调试信息
print(f"Debug - API Secret: {api_secret}") # 调试信息
# 使用HMAC-SHA256算法生成签名
hmac_obj = hmac.new(
key=api_secret.encode('utf-8'),
msg=message.encode('utf-8'),
digestmod=hashlib.sha256
)
signature = hmac_obj.digest()
signature_b64 = base64.b64encode(signature).decode('utf-8')
return {
'signature': signature_b64,
'timestamp': timestamp,
'headers': {
'AVE-ACCESS-SIGN': signature_b64,
'AVE-ACCESS-TIMESTAMP': timestamp
},
'debug': {
'message': message, # 调试信息
'method': method, # 调试信息
'request_path': request_path # 调试信息
}
}