我对Huobi(cryptoexchange)REST API请求签名有问题。规则很明确(例如here)。 “ v1 /帐户/帐户”的示例-不带参数的GET:
URL参数:
AccessKeyId=dbye2sf5t7-d5829459-bf3aee27-67f62&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-11-11T12%3A17%3A57
预签名文本:
GET\napi.huobi.pro\n/v1/account/accounts\nAccessKeyId=dbye2sf5t7-d5829459-bf3aee27-67f62&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-11-11T12%3A17%3A57
Hmac SHA256-带有私钥的预签名文本的签名(已验证here):
auZl70i2qsUb7+U9yYEEY1bwzLypWIM7qF1pBAJcvfc=
要获取的URL:https://api.huobi.pro/v1/account/accounts?AccessKeyId=dbye2sf5t7-d5829459-bf3aee27-67f62&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2020-11-11T12%3A17%3A57&Signature=auZl70i2qsUb7%2BU9yYEEY1bwzLypWIM7qF1pBAJcvfc%3D
响应为:
{"status":"error","err-code":"api-signature-not-valid","err-msg":"Signature not valid: Verification failure [校验失败]","data":null}
我做错了什么?我搜索了许多代码示例,但未发现错误...
答案 0 :(得分:0)
我在同一个端点上遇到了这个问题。我不确定您使用什么代码来签署您的请求。这是我的:
class HuobiAuth(requests.auth.AuthBase):
def __init__(self, api_key: str, secret_key: str) -> None:
self.api_key: str = api_key
self.secret_key: str = secret_key
@staticmethod
def create_sign(p_params: Dict, method: str, host_url: str, request_path: str, secret_key: str):
sorted_params = sorted(p_params.items(), key=lambda d: d[0], reverse=False)
# encode_params = urllib.urlencode(sorted_params)
encode_params = urllib.parse.urlencode(sorted_params)
payload = [method, host_url, request_path, encode_params]
payload = '\n'.join(payload)
payload = payload.encode(encoding='UTF8')
secret_key = secret_key.encode(encoding='UTF8')
digest = hmac.new(secret_key, payload, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(digest)
signature = signature.decode()
return signature
def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
params_to_sign = {'AccessKeyId': self.api_key,
'SignatureMethod': 'HmacSHA256',
'SignatureVersion': '2',
'Timestamp': timestamp}
host_name = urllib.parse.urlparse(request.url).hostname.lower()
params_to_sign['Signature'] = self.create_sign(params_to_sign, request.method, host_name, request.path_url, self.secret_key)
request.url += '?' + urllib.parse.urlencode(params_to_sign)
return request
我最初的问题是我没有使用 request.method
我有一个硬编码的“POST”,我必须从原始来源复制。
示例用法:
requests.post(url, json=your_data, auth=HuobiAuth(key, secret))