使用PHP CURL生成HMAC SHA256签名请求时遇「签名无效」报错求助
排查Binance API签名无效(Signature not valid)的问题
我帮你仔细梳理了代码和Binance的签名规则,几个关键错误导致了签名验证失败,下面逐一分析并给出修正方案:
核心问题分析
- 错误的参数转义与编码:你手动拼接参数时用了
&(HTML转义的&符号),还对整个查询字符串做了urlencode,但Binance要求签名用的totalParams是原始的键值对用&直接拼接,不需要整体URL编码(仅参数值含特殊字符时才单独编码,你的参数值都是合法的,不需要额外处理)。 - 签名参数不完整:
totalParams必须包含所有请求参数,包括recvWindow和timestamp,你之前只计算了symbol、side等基础参数,漏掉了这两个必填的签名要素,这是签名不匹配的核心原因。 - 请求方式与参数位置冲突:你使用了POST请求,但把所有参数放在URL中,虽然Binance允许这种方式,但更规范的做法是POST请求将参数放在请求体中,同时确保所有参数都被纳入签名计算范围。
修正后的代码
<?php $ch = curl_init(); $timestamp = round(microtime(true) * 1000); $secret = 'bmrLfulhggHgudLEHzRj7zNz**************p3KladNAcI4qLg'; $apiKey = 'EAXHTI2ZyuWqVdVC*****************RsVrptYUnl2XYM9f'; // 1. 整理所有需要传递的参数,包含timestamp和recvWindow $params = [ 'symbol' => 'LTCBTC', 'side' => 'BUY', 'type' => 'LIMIT', 'timeInForce' => 'GTC', 'quantity' => '1', 'price' => '0.1', 'recvWindow' => '50000', 'timestamp' => $timestamp ]; // 2. 自动拼接成符合要求的totalParams字符串,避免手动拼接出错 $totalParams = http_build_query($params, '', '&'); // 3. 用secretKey计算HMAC SHA256签名 $signature = hash_hmac('SHA256', $totalParams, $secret); // 4. 将签名加入参数列表 $params['signature'] = $signature; // 配置CURL请求 curl_setopt($ch, CURLOPT_URL, "https://api.binance.com/api/v3/order/test"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); // POST体传递参数 $headers = array(); $headers[] = "X-Mbx-Apikey: " . $apiKey; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); print_r($result); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close ($ch); ?>
关键修改说明
- 使用
http_build_query自动拼接参数,既避免了手动写字符串的错误,又能正确处理参数值的编码(如果有特殊字符的话)。 - 签名计算包含了所有必填参数(timestamp、recvWindow),完全符合Binance对
totalParams的定义。 - 改用POST请求体传递参数,更贴合Binance API的规范,同时确保签名覆盖了所有请求参数。
内容的提问来源于stack exchange,提问作者user3306814
相关产品推荐
相关产品推荐

