Hi i have this script in bash for huobi exchange (
https://www.htx.com/en-us/opend/newApiPages/?id=419[
^])
access_key=""
secret_key=""
host="api.huobi.pro"
path="/v1/account/accounts"
method="GET"
timestamp() {
date -u +"%Y-%m-%dT%H:%M:%S" | sed 's/:/%3A/g'
}
urlencode() {
local string="${1}"
local strlen=${
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
generate_signature() {
local params="AccessKeyId=$access_key&SignatureVersion=2&SignatureMethod=HmacSHA256&Timestamp=$(timestamp)"
local pre_signed_string="$method\n$host\n$path\n$params"
echo -en "${pre_signed_string}" | openssl dgst -sha256 -hmac "${secret_key}" -binary | base64
}
send_request() {
local signature=$(generate_signature)
local signed_params="AccessKeyId=$access_key&SignatureVersion=2&SignatureMethod=HmacSHA256&Timestamp=$(timestamp)&Signature=$(urlencode "$signature")"
local request_url="https://${host}${path}?${signed_params}"
echo "Full request URL: $request_url"
curl -s -H "Content-Type: application/x-www-form-urlencoded" -X GET "${request_url}"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
response=$(send_request)
echo "Response: $response"
fi
its return
{"status":"error","err-code":"api-signature-not-valid","err-msg":"Signature not valid: Verification failure [校验失败]","data":null} my signature is: 185cddeb6b6b6be76e1f5b917f3188dc52349cd67d91136dc90a28be8f43d71e
but
if i run this python script:
import time
from urllib import parse
import requests
from urllib import parse
from datetime import datetime, timezone
import hmac
import base64
import hashlib
import logger
import json
import urllib.parse
class UrlParamsBuilder(object):
def __init__(self):
self.param_map = dict()
self.post_map = dict()
self.post_list = list()
def put_url(self, name, value):
if value is not None:
if isinstance(value, (list, dict)):
self.param_map[name] = value
else:
self.param_map[name] = str(value)
def put_post(self, name, value):
if value is not None:
if isinstance(value, (list, dict)):
self.post_map[name] = value
else:
self.post_map[name] = str(value)
def build_url(self):
if len(self.param_map) == 0:
return ""
encoded_param = urllib.parse.urlencode(self.param_map)
return "?" + encoded_param
def build_url_to_json(self):
return json.dumps(self.param_map)
def _get_url_suffix(method: str, access_key: str, secret_key: str, host: str, path: str,params: dict) -> str:
timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S')
builder = UrlParamsBuilder()
if params != None and method=="GET":
for key, value in params.items():
builder.put_url(key, value)
builder.put_url("AccessKeyId", access_key)
builder.put_url("SignatureVersion", "2")
builder.put_url("SignatureMethod", "HmacSHA256")
builder.put_url("Timestamp", timestamp)
keys = sorted(builder.param_map.keys())
qs0 = '&'.join(['%s=%s' % (key, parse.quote(builder.param_map[key], safe='')) for key in keys])
payload0 = '%s\n%s\n%s\n%s' % (method, host, path, qs0)
print("Valore utilizzato per creare la signature:", payload0) # Stampiamo il valore utilizzato per creare la signature
dig = hmac.new(secret_key.encode('utf-8'), msg=payload0.encode('utf-8'), digestmod=hashlib.sha256).digest()
s = base64.b64encode(dig).decode()
builder.put_url("Signature", s)
suffix = builder.build_url()
return suffix
def post(access_key: str, secret_key: str, host: str, path: str, data: dict = None) -> json:
try:
url = 'https://{}{}{}'.format(host, path, _get_url_suffix(
'POST', access_key, secret_key, host, path,None))
headers = {'Accept': 'application/json',
'Content-type': 'application/json'}
res = requests.post(url, json=data, headers=headers)
data = res.json()
return data
except Exception as e:
logger.error(e)
return None
def getcurrentdate():
pass
current_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
return current_date
def datetotimestamp(date):
datetime_obj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S.%f")
ret_stamp = int(time.mktime(datetime_obj.timetuple()) * 1000.0 + datetime_obj.microsecond / 1000.0)
return ret_stamp
def get(access_key: str, secret_key: str, host: str, path: str, params: dict ) -> json:
try:
url = 'https://{}{}{}'.format(host, path, _get_url_suffix(
'GET', access_key, secret_key, host, path,params))
headers = {'Content-type': 'application/x-www-form-urlencoded'}
print("Full_request_Url:",url)
res = requests.get(url, headers=headers)
data = res.json()
return data
except Exception as e:
logger.error(e)
return None
if __name__ == '__main__':
# APIkey
access_key = ''
secret_key = ''
host = 'api.huobi.pro'
path = '/v1/account/accounts'
params = dict()
acc_json = get(access_key, secret_key, host, path, params)
print("response", acc_json)
it work and return sign iZD79Fj4H2yAwY%2F%2FkxyKE7WWLVBpbT9Rfz%2BAXDuG%2FsA%3D (little bit short ) with the same input param why ?
What I have tried:
other bash version that i tested is
_Huobi_Get_all_Accounts_of_the_Current_User() {
_Init_Huobi_ApiSecretIDData "huobi"
local PRE_URL="v1/account/accounts"
echo "PART OF URL:----> $PRE_URL"
local apiUrl="$HTXApiUrl$PRE_URL"
echo "COMPLEATE ULR:----> $apiUrl"
local ACCESSKEYID="AccessKeyId=$HTXApiKey"
echo "ACCESS KEY: -----> $ACCESSKEYID"
local SIGNATUREVERSION="SignatureVersion=2"
echo "VERSION SIGN:-----> $SIGNATUREVERSION"
local SIGNATUREMETHOD="SignatureMethod=HmacSHA256"
echo "METHOD SIGN: -----> $SIGNATUREMETHOD"
local TIMESTAMP="Timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S" | sed 's/:/%3A/g')"
echo "TIMESTAMP: ----> $TIMESTAMP"
# La stringa di query deve essere ordinata in base all'ASCII prima di essere firmata
local QUERYSTRING=$(echo -n "$ACCESSKEYID&$SIGNATUREMETHOD&$SIGNATUREVERSION&$TIMESTAMP" | sort)
echo "QUERY 4 RAW MESSAGE: ------> $QUERYSTRING"
# La firma viene creata normalizzando la stringa di query
local RAW_MESSAGE="GET\n$HTXApiUrl\n$PRE_URL\n$QUERYSTRING"
echo "RAW MESSAGE 4 SIGNATURE: ------> $RAW_MESSAGE"
local SIGNATURE=$(echo -n "$RAW_MESSAGE" | openssl dgst -sha256 -hmac $HTXSecretKey | cut -c 18-)
#local SIGNATURE=$(echo -n "GET"$'\x0A'"$HTXApiUrl"$'\x0A'"$PRE_URL"$'\x0A'"$QUERYSTRING" | openssl dgst -sha256 -hmac $HTXSecretKey | cut -c 18-)
echo "SIGNATURE -----> $SIGNATURE"
local SIGNATUREPARAM="Signature=$SIGNATURE"
#echo "$SIGNATUREPARAM"
# Utilizza curl e cattura l'output nella variabile response
response=$(curl -s -H "Content-type: application/x-www-form-urlencoded" -X GET "$apiUrl?$QUERYSTRING&$SIGNATUREPARAM")
echo "CALL CURL WITH ALL FEED: ---->curl -H 'Content-Type: application/x-www-form-urlencoded' -X GET \"$apiUrl?$QUERYSTRING&$SIGNATUREPARAM\""
}