编程 Binance 私有 API 报 -1021 / -1022:SIGNED 端点签名与时间戳排查

2026-09-13 00:05:23

Binance 私有 API 报 -1021 / -1022:SIGNED 端点签名与时间戳排查

文档与源码:

  • Binance Spot API 文档:
  • 开发者站点:

请求 /api/v3/order/api/v3/account 返回 400,body 里常见这几种:

{"code":-1021,"msg":"Timestamp for this request is outside of the recvWindow."}
{"code":-1022,"msg":"Signature for this request is not valid."}
{"code":-1100,"msg":"Illegal characters found in parameter 'signature'."}

SIGNED 端点需要什么

TRADE 与 USER_DATA 端点是 SIGNED 端点。除了业务参数,还必须带:

  • signature:放在 query string 或 request body 里。
  • timestamp:请求创建/发送时的毫秒时间戳,也支持微秒。
  • recvWindow:可选,指定 timestamp 之后请求有效的毫秒数。

signature 应放在参数列表最后。HMAC 产生的签名不区分大小写,RSA 与 Ed25519 签名区分大小写。签名是 hex 字符串,合法范围 ^[A-Fa-f0-9]{64}$,也就是 64 位 hex。长度或字符不对会报 -1100 Illegal characters found in parameter 'signature'

签名算法:HMAC-SHA256 对 totalParams 签名

secretKey 作为 key,totalParams 作为待签值做 keyed HMAC。totalParams 是 query string 与 request body 的拼接:query string concatenated with request body。

以下单 LIMIT 为例,参数:

symbol=LTCBTC, side=BUY, type=LIMIT, timeInForce=GTC, quantity=1, price=0.1, recvWindow=5000, timestamp=1499827319559

拼成:

symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559

用 openssl 复现:

echo -n "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559" | openssl dgst -sha256 -hmac "SECRET_KEY"

输出:

c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71

请求:

curl -H "X-MBX-APIKEY: $apiKey" -X POST 'https://api.binance.com/api/v3/order?symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559&signature=c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71'

Python 等价写法:

import hashlib
import hmac

secret = "SECRET_KEY"
total_params = (
"symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC"
"&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559"
)
signature = hmac.new(
secret.encode(), total_params.encode(), hashlib.sha256
).hexdigest()
print(signature)
# c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71

hexdigest() 默认输出小写 hex。

recvWindow 与服务端判定

recvWindow 不传时默认 5000 毫秒,最大 60000 毫秒,支持最多三位小数,例如 6000.346,用于精确到微秒。官方建议用小值,5000 或更小,上限不能超过 60000。

服务端判定逻辑:

serverTime = getCurrentTime()
if (timestamp "

如果服务器与本地时钟不同步,例如本地是 GMT+2,时间戳不一致会返回 400。工程上先取服务器时间:

curl "https://api.binance.com/api/v3/time"

用返回的 serverTime 校准本地偏移,再生成 timestamp。本地时钟同步可以交给 NTP,但不要假设它一定准。

常见错误对照

错误码含义常见原因
-1021Timestamp for this request is outside of the recvWindow发送的 timestampserverTime - recvWindow 之外;或 timestamp 比服务器时间超前超过 1000ms
-1022Signature for this request is not valid某个参数格式不对,例如 recvWindow 必须是整数而不是字符串;参数拼接/顺序变化;代理改参数;secret 不对。python-binance FAQ 也提到可能需要重新生成 API Key 与 Secret
-1100Illegal characters found in parameter 'signature'signature 不是 64 位 hex,长度或字符不满足 ^[A-Fa-f0-9]{64}$
-2015Invalid API-key, IP, or permissions for actionkey、IP 或权限不匹配
-1003Too many requests被限流

几个会让签名直接失效的边界

  • 签名前统一按字典序或固定顺序拼接参数。顺序一变,totalParams 变,-1022
  • 不要把 secretKey 放前端。签名必须在后端完成。
  • 中间层代理或网关如果改动 query 参数、重编码 body,签名会失效,报 -1022
  • 本地时钟只用 NTP 校准还不够,SIGNED 请求应基于 /api/v3/timeserverTime 计算偏移。
  • signature 放在参数最后,但计算 totalParams 时不要把它拼进去。
复制全文 生成海报 crypto api 交易所 API Binance HMAC 签名 接口对接

推荐文章

程序员茄子在线接单