《淘宝TOP API Sign签名算法详解与MD5/HMAC实现(Python/Java/PHP)》

简介: 本文详解淘宝TOP API签名算法(MD5/HMAC-MD5),涵盖4步核心流程:参数过滤→ASCII升序→KV拼接→签名计算,并提供Python/Java/PHP三语言可运行实现。附排错清单与面试要点,助你一次通过TOP接入,规避“Invalid Signature”高频错误。(239字)

🔐 淘宝TOP API Sign签名算法详解与MD5/HMAC实现(Python/Java/PHP)

淘宝开放平台(TOP)所有请求必须带 sign 参数,签名错误是TOP接入排名第一的坑。弄懂下面规则,所有接口(商品/订单/物流/退款)一遍通。

一、TOP签名算法官方规范(重点记这4步)

假设:
• app_key = 123456

• app_secret = 6a8b0c1d2e3f4g5h

• API参数:method=taobao.item.get, num_iid=654321, fields=title,price, format=json, v=2.0

✅ Step 1:收集所有API参数

包括公共参数(app_key, method, timestamp, format, v, sign_method)+业务参数(num_iid, fields等)
剔除:sign 字段、值为空(None/空字符串) 的参数、二进制文件字段

✅ Step 2:按参数名 ASCII 升序排序

app_key=123456
fields=title,price
format=json
method=taobao.item.get
num_iid=654321
sign_method=md5
timestamp=1700000000000
v=2.0

✅ Step 3:拼接 key+value(无=无&)

app_key123456fields title,priceformatjsonmethodtaobao.item.getnum_iid654321sign_methodmd5timestamp1700000000000v2.0

⚠️ 注意 fields 的值是 title,price,原样拼入,逗号不编码不省略

✅ Step 4:计算签名

■ MD5方式(最常用)

待签名串 = APP_SECRET + 上步字符串 + APP_SECRET
sign = MD5(待签名串).upper()

例:6a8b0c1d2e3f4g5h + 拼接串 + 6a8b0c1d2e3f4g5h → MD5 → 32位大写

■ HMAC-MD5方式(可选,需传 sign_method=hmac-md5)

sign = HMAC_MD5(AppSecret, 拼接串).hexdigest().upper()

拼接串首尾不再加AppSecret,直接用排序后KV串做HMAC原文。

二、Python实现(推荐直接用)

top_sign.py

import hashlib
import hmac
from typing import Dict, Optional

def top_sign(params: Dict[str, Optional[str]], app_secret: str,
sign_method: str = "md5") -> str:
"""
淘宝TOP API签名
params: 所有API参数(不含sign, 空值已剔除)
app_secret: AppSecret
sign_method: 'md5' | 'hmac-md5'
return: 大写签名串
"""

# 1. 剔除空值 & sign
filtered = {
    k: v for k, v in params.items()
    if v is not None and str(v).strip() != "" and k != "sign"
}

# 2. ASCII升序
sorted_items = sorted(filtered.items(), key=lambda x: x[0])

# 3. 拼 key+value
qs = "".join(f"{k}{v}" for k, v in sorted_items)

# 4. 签名
if sign_method == "hmac-md5":
    sig = hmac.new(
        app_secret.encode("utf-8"),
        qs.encode("utf-8"),
        hashlib.md5
    ).hexdigest().upper()
else:  # md5
    raw = f"{app_secret}{qs}{app_secret}"
    sig = hashlib.md5(raw.encode("utf-8")).hexdigest().upper()

return sig

===================== 验证示例 =====================

if name == "main":
APP_SECRET = "YOUR_APP_SECRET"

api_params = {
    "method": "taobao.item.get",
    "app_key": "YOUR_APP_KEY",
    "timestamp": str(1700000000000),   # 替换真实毫秒时间戳
    "format": "json",
    "v": "2.0",
    "sign_method": "md5",
    "num_iid": "654321098765",
    "fields": "title,price,pic_url"
    # "session": "ACCESS_TOKEN"  # 订单类接口需要
}

sign = top_sign(api_params, APP_SECRET, sign_method="md5")
api_params["sign"] = sign

print("✅ 计算签名:", sign)
print("📦 请求参数示例:")
for k, v in api_params.items():
    print(f"   {k} = {v}")

三、Java实现

// TopSignUtil.java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.*;

封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex

public class TopSignUtil {

public static String signMD5(Map<String, String> params, String appSecret) throws Exception {
    // 1. 去空 & 去sign
    Map<String, String> filtered = new TreeMap<>();
    for (Map.Entry<String, String> e : params.entrySet()) {
        if (!"sign".equals(e.getKey()) && e.getValue() != null && !e.getValue().trim().isEmpty()) {
            filtered.put(e.getKey(), e.getValue());
        }
    }

    // 2. TreeMap已按key升序,拼KV
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, String> e : filtered.entrySet()) {
        sb.append(e.getKey()).append(e.getValue());
    }

    // 3. 首尾加secret → MD5
    String toSign = appSecret + sb.toString() + appSecret;
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] digest = md.digest(toSign.getBytes("UTF-8"));
    StringBuilder hex = new StringBuilder();
    for (byte b : digest) {
        hex.append(String.format("%02X", b & 0xFF));
    }
    return hex.toString();
}

public static String signHmacMD5(Map<String, String> params, String appSecret) throws Exception {
    Map<String, String> filtered = new TreeMap<>();
    for (Map.Entry<String, String> e : params.entrySet()) {
        if (!"sign".equals(e.getKey()) && e.getValue() != null && !e.getValue().trim().isEmpty())
            filtered.put(e.getKey(), e.getValue());
    }

    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, String> e : filtered.entrySet()) {
        sb.append(e.getKey()).append(e.getValue());
    }

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacMD5"));
    byte[] raw = mac.doFinal(sb.toString().getBytes("UTF-8"));
    StringBuilder hex = new StringBuilder();
    for (byte b : raw) hex.append(String.format("%02X", b & 0xFF));
    return hex.toString();
}

// 用法:
// Map<String,String> p = new HashMap<>();
// p.put("method","taobao.item.get"); ...
// String sign = TopSignUtil.signMD5(p, APP_SECRET);

}

四、PHP实现

<?php
// top_sign.php
function topSign(array $params, string $appSecret, string $method = 'md5'): string {
// 1. 去空去sign
unset($params['sign']);
$filtered = array_filter($params, fn($v) => $v !== null && $v !== '');

// 2. key升序
ksort($filtered);

// 3. 拼KV
$str = '';
foreach ($filtered as $k => $v) {
    $str .= $k . $v;
}

// 4. 签名
if ($method === 'hmac-md5') {
    return strtoupper(hash_hmac('md5', $str, $appSecret));
}
return strtoupper(md5($appSecret . $str . $appSecret));

}

// 示例
$params = [
'method' => 'taobao.item.get',
'app_key' => 'YOUR_APP_KEY',
'timestamp'=> (string)(microtime(true)*1000),
'format' => 'json',
'v' => '2.0',
'sign_method'=>'md5',
'num_iid' => '654321098765',
'fields' => 'title,price,pic_url'
];
echo "sign = " . topSign($params, 'YOUR_APP_SECRET') . PHP_EOL;
?>

五、签名排错清单(TOP特有)

现象 原因 排查

Invalid Signature 时间戳单位错 必须 13位毫秒 int(time.time()*1000)

Invalid Signature 空值参入签名 严格过滤 None/''

Invalid Signature fields 值含空格被截断 保持原串,title,price 逗号分隔不动

偶发成功偶失败 系统时钟偏差大 服务器NTP同步(±5分钟内)

HmacMD5返回签名错 sign_method 未传或传 hmac-md5 API参数加 "sign_method":"hmac-md5"

图片上传接口签错 二进制不参与签名 仅业务参数字段签,Filedata 放 multipart body

六、面试一句话

淘宝TOP签名 = 参数按key ASCII升序拼key+value → 首尾加AppSecret → MD5 → 大写(Hmac-MD5变体不加首尾Secret,直接用HMAC);空值/sign不参入,timestamp必须用13位毫秒。

需要我把这个 top_sign() 集成进之前的 商品详情 / 订单同步 / OAuth Client 给你完整可运行TOP对接模块吗?

相关文章
|
2月前
|
Web App开发 人工智能 Cloud Native
一人买多用不完,多人分享被封号——"Key池化"破解 AI 订阅共享困局
Claude用户面临“独用浪费、共享封号”困局:Max 20x额度闲置,多人拼车却因IP跳变、指纹泄露等触发风控。Key池化方案通过本地代理+虚拟Key分发,实现额度共享而不共号,规避风控,降低成本(3人仅$200/月),提升安全与体验。
604 7
|
2月前
|
算法 安全 API
《淘宝开放平台TOP API接入全指南:注册、AppKey获取、签名算法与沙箱调试(2026)》(附python源码)
淘宝开放平台(TOP)是淘宝/天猫官方API体系,区别于1688。本文涵盖注册、AppKey获取、MD5/HmacMD5签名(ASCII排序+首尾拼Secret)、沙箱调试(`tbsandbox.com`网关)及Python可运行示例,含`taobao.item.get`调通验证与避坑指南。(239字)
|
2月前
|
人工智能 Cloud Native 关系型数据库
MySQL 8.4 LTS来了!从8.0到8.4,DBA必须知道的5个核心变化
MySQL 8.0社区版将于2026年结束生命周期,8.4 LTS作为首个长期支持版本,提供5年超长支持周期(至2031年)。本文从InnoDB并行查询、Redo Log动态容量、默认认证插件变更、参数默认值调整、云原生适配五个维度,梳理DBA升级前必须掌握的核心变化,并提供升级检查清单。
|
2月前
|
人工智能 安全 Cloud Native
Higress 新发布:AI Gateway 能力增强,Gateway API 及其推理扩展持续打磨
增强 AI 网关能力,持续打磨 Gateway API 及其推理扩展。
671 138
|
2月前
|
人工智能 运维 自然语言处理
「Agent 友好」的可观测:阿里云发布观测与智能运维 Skills
开发者只需在 Qoder 等 Agent 客户端中发出一句自然语言指令。借助云监控与STAROps Skill,Agent 即可自主完成数据接入、告警配置、根因诊断,并联动研发工具链完成代码修复与发布。
600 133
|
2月前
|
消息中间件 人工智能 Kafka
AI 时代,实时入湖正在告别 ETL:从 Kafka 到 Iceberg 的架构减法
本文围绕“零 ETL”这一趋势,讨论流数据入湖为什么需要做架构减法,并结合 Kafka × Table Bucket 的实践,分析一种将通用入湖能力前移到消息与表存储链路中的方案,如何在降低复杂度的同时,兼顾实时性、一致性、Schema 演进、CDC 语义与开放生态兼容。
426 133
|
JSON 数据格式 索引
记一次ES节点扩容、数据迁移实践
ElasticSearch、ES数据迁移、ES扩容
14534 1
人工智能 JSON 自然语言处理
45 1
|
2月前
|
缓存 Java Devops
云效 Maven 私有仓库实战:团队 jar 包依赖管理的 3 个高效配置,版本冲突率降低 80%
中小团队做 Java 开发,jar 包依赖管理经常出现三类问题:公共模块改了没人通知导致编译失败、SNAPSHOT 版本不一致引发线上诡异 bug、自建 Nexus 服务器维护成本高。阿里云云效制品仓库 Packages 提供免费 Maven 私有仓库,5 分钟开通,通过 settings.xml + pom.xml + CI/CD 流水线三步配置即可实现团队 jar 包统一管理。本文从创建仓库、settings.xml 完整配置、本地/流水线上传下载 jar 包、到 version 冲突排查,覆盖全流程,实测将团队依赖管理时间缩短 80%。
|
2月前
|
SQL 人工智能 监控
当我们在聊 Agent 时,我们到底在聊什么——兼谈 Skills 和 Workflow 的定位
本文厘清AI领域最易混淆的三大概念:Workflow(预定义流程)、Skills(封装化AI能力)与Agent(运行时自主决策)。核心差异在于“自主决策链条长度”——Workflow靠人工设计、Skills重模块复用、Agent擅动态规划。三者非替代关系,而应按场景组合使用,避免概念滥用。

热门文章

最新文章