×

🔐 1688开放平台API Sign签名算法详解(Java / Python / PHP 实现)

万邦科技Lex 万邦科技Lex 发表于2026-06-10 09:31:42 浏览29 评论0

抢沙发发表评论

1688(AliExpress/1688 Open Platform)所有API请求都必须带 sign参数,签名算法是接入最容易出错的地方。弄懂它,后续所有接口(商品、订单、物流、图片搜索)都能一遍通。


一、1688 官方签名规则(重点记这4步)

假设已有:
  • app_key = 123456

  • app_secret = 7a3b9c8d...(前后都会用到)

  • 业务参数:method=alibaba.item.get, item_id=610947572360

✅ Step 1:收集所有业务参数(不含 signfile二进制)

app_key, format, method, timestamp, v, sign_method, session(如有)
+ 业务字段 (item_id 等)

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

app_key=123456
format=json
item_id=610947572360
method=alibaba.item.get
sign_method=md5
timestamp=1700000000000
v=2.0

✅ Step 3:拼接成 key+value字符串(无 =&

app_key123456formatjsonitem_id610947572360methodalibaba.item.getsign_methodmd5timestamp1700000000000v2.0

✅ Step 4:首尾拼 AppSecret → MD5 → 大写

待签名串 = APP_SECRET + 上一步字符串 + APP_SECRET
sign = MD5(待签名串).upper()
⚠️ 最常见错误
  • sign参入签名 ✘

  • 时间戳用秒而非毫秒

  • 参数值为 None/空字符串参入签名(1688要求剔除值为空的参数)✘

  • Base64图片等超长字段参入签名时未用原串 ✘


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

# ali1688_sign.py
import hashlib
import time
from typing import Dict, Optional
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
def generate_1688_sign(params: Dict[str, Optional[str]], app_secret: str) -> str:
    """
    1688 Open Platform Sign 生成 (MD5)
    
    Args:
        params:    所有API参数(不含sign, 不含None值)
        app_secret: AppSecret
    
    Returns:
        大写32位MD5签名串
    """
    # 1. 剔除空值
    filtered = {k: v for k, v in params.items() if v is not None and str(v).strip() != ''}
    
    # 2. 按 key ASCII 升序排序
    sorted_items = sorted(filtered.items(), key=lambda x: x[0])
    
    # 3. 拼接 key+value
    param_str = ''.join(f"{k}{v}" for k, v in sorted_items)
    
    # 4. 首尾拼 secret → MD5 → 大写
    sign_str = f"{app_secret}{param_str}{app_secret}"
    return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()


# ===================== 使用示例 =====================
if __name__ == "__main__":
    APP_KEY = "YOUR_APP_KEY"
    APP_SECRET = "YOUR_APP_SECRET"
    
    api_params = {
        "method": "alibaba.item.get",
        "app_key": APP_KEY,
        "timestamp": str(int(time.time() * 1000)),   # 毫秒级!
        "format": "json",
        "v": "2.0",
        "sign_method": "md5",
        "item_id": "610947572360",
        # "session": "ACCESS_TOKEN"  # 订单类接口需要
    }
    
    sign = generate_1688_sign(api_params, APP_SECRET)
    api_params["sign"] = sign
    
    print("✅ 签名结果:", sign)
    print("📦 请求参数示例:")
    for k, v in api_params.items():
        print(f"  {k} = {v}")

三、Java 实现

// Ali1688SignUtil.java
import java.util.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
public class Ali1688SignUtil {

    public static String generateSign(Map<String, String> params, String appSecret)
            throws NoSuchAlgorithmException {

        // 1. 移除空值
        Map<String, String> filtered = new TreeMap<>();
        for (Map.Entry<String, String> e : params.entrySet()) {
            if (e.getKey() != null && e.getValue() != null && !e.getValue().trim().isEmpty()) {
                filtered.put(e.getKey(), e.getValue());
            }
        }

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

        // 3. 首尾拼 secret
        String toSign = appSecret + sb.toString() + appSecret;

        // 4. MD5 大写
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(toSign.getBytes(java.nio.charset.StandardCharsets.UTF_8));
        StringBuilder hex = new StringBuilder();
        for (byte b : digest) {
            hex.append(String.format("%02X", b & 0xFF));
        }
        return hex.toString();
    }

    // 用法示例
    public static void main(String[] args) throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("method", "alibaba.item.get");
        params.put("app_key", "YOUR_APP_KEY");
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("format", "json");
        params.put("v", "2.0");
        params.put("sign_method", "md5");
        params.put("item_id", "610947572360");

        String sign = generateSign(params, "YOUR_APP_SECRET");
        System.out.println("sign = " + sign);
    }
}

四、PHP 实现

<?php
// ali1688_sign.php

function generate1688Sign(array $params, string $appSecret): string {
    // 1. 去掉空值及sign本身
    unset($params['sign']);
    $filtered = array_filter($params, fn($v) => $v !== null && $v !== '');

    // 2. 按键 ASCII 升序
    ksort($filtered);

    // 3. 拼接 key+value
    $str = '';
    foreach ($filtered as $k => $v) {
        $str .= $k . $v;
    }

    // 4. MD5 首尾拼 secret → 大写
    $toSign = $appSecret . $str . $appSecret;
    return strtoupper(md5($toSign));
}
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
// ---- 示例 ----
$params = [
    'method'   => 'alibaba.item.get',
    'app_key'  => 'YOUR_APP_KEY',
    'timestamp' => (string)(microtime(true) * 1000), // 毫秒
    'format'   => 'json',
    'v'        => '2.0',
    'sign_method' => 'md5',
    'item_id'  => '610947572360',
];

$sign = generate1688Sign($params, 'YOUR_APP_SECRET');
$params['sign'] = $sign;

echo "sign = {$sign}\n";
?>

五、签名自检 & 排错清单

现象
原因
排查
Invalid Signature
时间戳单位错
必须 13位毫秒 int(time.time()*1000)
Invalid Signature
参数含空格或编码
确保 UTF-8,中文正常参与签名不 URL-Encode
sign fail
None值参入签名
严格过滤空值
偶尔成功偶尔失败
系统时间偏差大
服务器时间需 NTP 同步(±5分钟内)
图片搜索报签名错
Base64 含换行/data:image前缀
用裸 Base64 串,不参与截断

六、面试/对接一句话总结

1688签名 = 按参数名ASCII升序拼 key+value→ 首尾加AppSecret → MD5 → 大写,空值剔除、timestamp用毫秒、sign本身不参与签名。
需要我把这个 sign函数集成进之前的 商品搜索 / 订单同步 / 图片搜索 Client 中给你完整可调用的模块吗?


群贤毕至

访客