调用Huobi API时认证始终失败,返回api-signature-not-valid求助
api-signature-not-valid) I’ve gone through your PHP code and spotted several key issues that are causing the signature validation to fail. Let’s break them down and fix the code step by step:
1. Extra Spaces in the Signature Base String
Your current $pre_sig has unnecessary spaces after each newline (e.g., \n api.huobi.pro instead of \napi.huobi.pro). Huobi's signature rules require strict formatting—any extra whitespace will make the computed signature mismatch what the server expects. The correct format is:
HTTP_METHOD\nHOST\nREQUEST_PATH\nQUERY_PARAMS_SORTED
2. Invalid Timestamp Format
Huobi requires the Timestamp to be in UTC ISO8601 format with a Z suffix (e.g., 2024-05-20T14:30:00Z). Your code generates a timestamp without the Z, which will fail the server's time validation check.
3. Unencoded Signature in URL
The base64-encoded signature may contain special characters like +, /, or =. If you paste this directly into the URL, it will be misinterpreted by the server—you need to URL-encode the signature first.
4. Unsorted Query Parameters (Best Practice)
While your current parameter order doesn’t break things, Huobi requires query parameters to be sorted lexicographically before generating the signature. Following this rule prevents issues when you add more parameters later.
Corrected Full Code
<?php date_default_timezone_set("UTC"); // Explicitly set to UTC for clarity $api_key = "xxxxxxxxxxxxxxxxxxxxxxxxx"; $api_secret = "yyyyyyyyyyyyyyyyyyyyyyyyyyy"; // Generate valid UTC timestamp with Z suffix $timestamp = date('Y-m-d\TH:i:s\Z'); // Use rawurlencode for RFC 3986-compliant encoding function url_encode($string) { return rawurlencode($string); } // Keep your HTTP request function, added curl error checking for debugging function http_request($method = 'GET', $url, $headers, $data = null) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, TRUE); if ($method === 'POST') { curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } elseif ($method === 'DELETE') { curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); } if (!empty($headers)) { curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); $output = curl_exec($curl); // Add debugging for curl errors if (curl_errno($curl)) { echo 'Curl Error: ' . curl_error($curl); } curl_close($curl); return $output; } // 1. Build and sort query parameters lexicographically $query_params = [ 'AccessKeyId' => $api_key, 'SignatureMethod' => 'HmacSHA256', 'SignatureVersion' => '2', 'Timestamp' => $timestamp ]; ksort($query_params); // 2. Build query string with RFC 3986 encoding $query_string = http_build_query($query_params, '', '&', PHP_QUERY_RFC3986); // 3. Construct the signature base string (no extra spaces!) $pre_sig = "GET\napi.huobi.pro\n/v1/account/accounts\n$query_string"; // 4. Compute HMAC-SHA256 signature and base64 encode $signature = base64_encode(hash_hmac("sha256", $pre_sig, $api_secret, true)); // 5. URL-encode the signature and build the final URL $final_url = "https://api.huobi.pro/v1/account/accounts?$query_string&Signature=" . url_encode($signature); $headers = ["Content-Type: application/json"]; $response = http_request('GET', $final_url, $headers); var_dump($response); ?>
Key Changes Explained
- Timestamp Format: Switched to
date('Y-m-d\TH:i:s\Z')to generate the required UTC time with aZsuffix. - Signature Base String: Removed extra spaces after newlines to match Huobi's strict formatting rules.
- Parameter Sorting: Used
ksort()to sort query parameters lexicographically, adhering to Huobi's signature requirements. - Signature Encoding: Applied
rawurlencodeto the base64 signature to handle special characters correctly in the URL. - URL Encoding: Replaced
urlencodewithrawurlencodefor RFC 3986 compliance, which is standard for API requests.
Additional Tips
- Ensure your server's time is synchronized with UTC (use NTP to avoid drift)—Huobi rejects requests with timestamps more than 5 minutes off from the server time.
- Double-check your API Key and Secret to make sure there are no typos or extra spaces.
内容的提问来源于stack exchange,提问作者Mishkin

