跳到主要内容

请求鉴权类型

  • 每个函数都有自己的鉴权类型,鉴权类型决定了访问时应当进行何种鉴权。
    • 鉴权类型会在本文档中各个函数名称旁声明。比如 下新的订单 (TRADE)
    • 如果没有特殊声明即默认为 NONE
鉴权类型API key签名描述
NONE公开市场数据
TRADErequiredrequired在交易所交易,下单和取消订单
USER_DATArequiredrequired私人账户信息,例如订单状态和交易历史
USER_STREAMrequired管理用户数据流订阅
MARKET_DATArequired历史市场数据访问
  • 函数鉴权需要指定和验证有效的 API key。
    • API key 可以在币安账户的 API 管理 页面创建。
    • API key和密钥都是大小写敏感的。 切勿与任何人共享它们。 如果您发现您的账户有异常活动,请立即撤销所有keys并联系币安客服。
  • API key 可以配置为仅允许访问某些类型的函数鉴权。
    • 例如,可以拥有一个 API key 有 TRADE 的权限进行交易,同时使用另一个 API key 有 USER_DATA 的权限来监控您的订单状态。
    • 默认情况下,API key 不能 交易。您需要先在 API 管理中开通交易权限。
  • TRADEUSER_DATA 请求也称为 SIGNED 请求。

SIGNED (TRADE 和 USER_DATA) 请求鉴权

时间同步安全

  • SIGNED 请求也必须发 timestamp 参数,其值应当是请求发送时刻的 unix 时间戳(毫秒)。

  • 还可以发送一个可选参数 recvWindow,指定请求保持有效的时间。

    • 如果 recvWindow 未发送,默认为5000毫秒
    • 最大 recvWindow 为60000毫秒。
  • 请求处理逻辑:

    if (timestamp < (serverTime + 1000) && (serverTime - timestamp) <= recvWindow) {
    // 处理请求
    } else {
    // 拒绝请求
    }

关于交易时效性 互联网状况并不完全稳定可靠,因此你的程序本地到币安服务器的时延会有抖动, 这是我们设置 recvWindow 的目所在。如果你从事高频交易,对交易时效性有较高的要求,可以灵活设置 recvWindow 以达到你的要求。

建议使用5000毫秒以下的 recvWindow

SIGNED 请求示例 (HMAC)

这是有关如何用 HMAC secret key 签署请求的分步指南。

示例 API key 和 secret key:

KeyValue
apiKeyvmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A
secretKeyNhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j

警告:请勿与任何人共享您的私钥。

示例密钥仅供参考。

请求示例:

{
"id": "4885f793-e5ad-4c3b-8f6c-55d891472b71",
"method": "order.place",
"params": {
"symbol": "BTCUSDT",
"side": "SELL",
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": "0.01000000",
"price": "52000.00",
"newOrderRespType": "ACK",
"recvWindow": 100,
"timestamp": 1645423376532,
"apiKey": "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A",
"signature": "------ 未填写 ------"
}
}

如您所见,目前缺少 signature 参数。

第一步:创建签名内容

除了 signature 之外,获取所有请求 params,然后按名称按字母顺序进行排序:

参数取值
apiKeyvmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A
newOrderRespTypeACK
price52000.00
quantity0.01000000
recvWindow100
sideSELL
symbolBTCUSDT
timeInForceGTC
timestamp1645423376532
typeLIMIT

将参数格式化为 参数=取值 对并用 & 分隔每个参数:

签名效载荷示例:

apiKey=vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A&newOrderRespType=ACK&price=52000.00&quantity=0.01000000&recvWindow=100&side=SELL&symbol=BTCUSDT&timeInForce=GTC&timestamp=1645423376532&type=LIMIT

第二步:计算签名

  1. secretKey 解释为 ASCII 数据,将其用作 HMAC-SHA-256 的 key。
  2. 将签名有效负载签名为 ASCII 数据。
  3. 将 HMAC-SHA-256 输出编码为 hex string。

请注意,apiKeysecretKey 和有效负载是大小写敏感的。 生成的签名值是不区分大小写的。

可以使用 OpenSSL 交叉检查您的签名算法实现:

$ echo -n 'apiKey=vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A&newOrderRespType=ACK&price=52000.00&quantity=0.01000000&recvWindow=100&side=SELL&symbol=BTCUSDT&timeInForce=GTC&timestamp=1645423376532&type=LIMIT' \
| openssl dgst -hex -sha256 -hmac 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j'

cc15477742bd704c29492d96c7ead9414dfd8e0ec4a00f947bb5bb454ddbd08a

第三步:添加 signatureparams

最后,使用生成的签名完成请求:

{
"id": "4885f793-e5ad-4c3b-8f6c-55d891472b71",
"method": "order.place",
"params": {
"symbol": "BTCUSDT",
"side": "SELL",
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": "0.01000000",
"price": "52000.00",
"newOrderRespType": "ACK",
"recvWindow": 100,
"timestamp": 1645423376532,
"apiKey": "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A",
"signature": "cc15477742bd704c29492d96c7ead9414dfd8e0ec4a00f947bb5bb454ddbd08a"
}
}

SIGNED 请求示例 (RSA)

KeyValue
apiKeyCAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ

对于这个例子,Private Key 将被引用为 test-prv-key.pem

警告:请勿与任何人共享您的私钥。 示例密钥仅供参考。

请求例子:

{
"id": "4885f793-e5ad-4c3b-8f6c-55d891472b71",
"method": "order.place",
"params": {
"symbol": "BTCUSDT",
"side": "SELL",
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": "0.01000000",
"price": "52000.00",
"newOrderRespType": "ACK",
"recvWindow": 100,
"timestamp": 1645423376532,
"apiKey": "CAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ",
"signature": "------ FILL ME ------"
}
}

第一步:计算 Payload

除了 signature,获取请求的所有其它 params,然后按名称字母顺序对它们进行排序:

参数取值
apiKeyCAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ
newOrderRespTypeACK
price52000.00
quantity0.01000000
recvWindow100
sideSELL
symbolBTCUSDT
timeInForceGTC
timestamp1645423376532
typeLIMIT

将参数格式化为 参数=取值 对并用 & 分隔每个参数:

apiKey=CAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ&newOrderRespType=ACK&price=52000.00&quantity=0.01000000&recvWindow=100&side=SELL&symbol=BTCUSDT&timeInForce=GTC&timestamp=1645423376532&type=LIMIT

第二步:计算签名

  1. 将签名有效负载编码为 ASCII 数据。
  2. 使用带有 SHA-256 hash 函数的 RSASSA-PKCS1-v1_5 算法对 payload 进行签名。
  3. 将输出编码为 base64 string。

请注意,apiKey, payload 和生成的签名值都是大小写敏感的。

您可以使用 OpenSSL 交叉检查您的签名算法:

$ echo -n 'apiKey=CAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ&newOrderRespType=ACK&price=52000.00&quantity=0.01000000&recvWindow=100&side=SELL&symbol=BTCUSDT&timeInForce=GTC&timestamp=1645423376532&type=LIMIT' \
| openssl dgst -sha256 -sign test-prv-key.pem \
| openssl enc -base64 -A

OJJaf8C/3VGrU4ATTR4GiUDqL2FboSE1Qw7UnnoYNfXTXHubIl1iaePGuGyfct4NPu5oVEZCH4Q6ZStfB1w4ssgu0uiB/Bg+fBrRFfVgVaLKBdYHMvT+ljUJzqVaeoThG9oXlduiw8PbS9U8DYAbDvWN3jqZLo4Z2YJbyovyDAvDTr/oC0+vssLqP7NmlNb3fF3Bj7StmOwJvQJTbRAtzxK5PP7OQe+0mbW+D7RqVkUiSswR8qJFWTeSe4nXXNIdZdueYhF/Xf25L+KitJS5IHdIHcKfEw3MQzHFb2ZsGWkjDQwxkwr7Noi0Zaa+gFtxCuatGFm9dFIyx217pmSHtA==

第三步:在请求的 params 参数添加签名值

最后,使用生成的签名完成请求:

{
"id": "4885f793-e5ad-4c3b-8f6c-55d891472b71",
"method": "order.place",
"params": {
"symbol": "BTCUSDT",
"side": "SELL",
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": "0.01000000",
"price": "52000.00",
"newOrderRespType": "ACK",
"recvWindow": 100,
"timestamp": 1645423376532,
"apiKey": "CAvIjXy3F44yW6Pou5k8Dy1swsYDWJZLeoK2r8G4cFDnE9nosRppc2eKc1T8TRTQ",
"signature": "OJJaf8C/3VGrU4ATTR4GiUDqL2FboSE1Qw7UnnoYNfXTXHubIl1iaePGuGyfct4NPu5oVEZCH4Q6ZStfB1w4ssgu0uiB/Bg+fBrRFfVgVaLKBdYHMvT+ljUJzqVaeoThG9oXlduiw8PbS9U8DYAbDvWN3jqZLo4Z2YJbyovyDAvDTr/oC0+vssLqP7NmlNb3fF3Bj7StmOwJvQJTbRAtzxK5PP7OQe+0mbW+D7RqVkUiSswR8qJFWTeSe4nXXNIdZdueYhF/Xf25L+KitJS5IHdIHcKfEw3MQzHFb2ZsGWkjDQwxkwr7Noi0Zaa+gFtxCuatGFm9dFIyx217pmSHtA=="
}
}

SIGNED 请求示例 (Ed25519)

我们建议使用 Ed25519 API keys,因为它在所有受支持的 API key 类型中提供最佳性能和安全性。

参数取值
symbolBTCUSDT
sideSELL
typeLIMIT
timeInForceGTC
quantity1
price0.2
timestamp1668481559918

下面的 Python 示例代码能说明如何使用 Ed25519 key 对 payload 进行签名。

#!/usr/bin/env python3
import base64
import time
import json
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from websocket import create_connection

# 设置身份验证:
API_KEY='替换成您的 API Key'
PRIVATE_KEY_PATH='test-prv-key.pem'
# 加载 private key。
# 在这个例子中,private key 没有加密,但我们建议使用强密码以提高安全性。
with open(PRIVATE_KEY_PATH, 'rb') as f:
private_key = load_pem_private_key(data=f.read(), password=None)
# 设置请求参数:
params = {
'apiKey': API_KEY,
'symbol': 'BTCUSDT',
'side': 'SELL',
'type': 'LIMIT',
'timeInForce': 'GTC',
'quantity': '1.0000000',
'price': '0.20'
}
# 参数中加时间戳:
timestamp = int(time.time() * 1000) # 以毫秒为单位的 UNIX 时间戳
params['timestamp'] = timestamp
# 参数中加签名:
payload = '&'.join([f'{param}={value}' for param, value in sorted(params.items())])
signature = base64.b64encode(private_key.sign(payload.encode('ASCII')))
params['signature'] = signature.decode('ASCII')
# 发送请求:
request = {
'id': 'my_new_order',
'method': 'order.place',
'params': params
}
ws = create_connection('wss://ws-api.binance.com:443/ws-api/v3')
ws.send(json.dumps(request))
result = ws.recv()
ws.close()
print(result)