Request POST for python, using encrypted signature provided by an API

3.7k views Asked by At

I am trying to get an API (of a cryptocurrency exchange) to let me update my phone number:

bitso_key = 'API_KEY'
bitso_secret ='API_SECRET'
consulta="phone_number"
phone_number=5534970199
nonce =  str(int(round(time.time() * 1000)))
http_method = "POST"
request_path = "/v3/"+consulta+"?"
json_payload={"phone_number":phone_number}

# Create signature
message = nonce+http_method+request_path+urlencode(json_payload)
#print(message)
signature = hmac.new(bitso_secret.encode('utf-8'),
                                        message.encode('utf-8'),
                                        hashlib.sha256).hexdigest()
# Build the auth header
auth_header = 'Bitso %s:%s:%s' % (bitso_key, nonce, signature)
url="https://api.bitso.com"+request_path


response = requests.post(url, data=json_payload, headers={"Authorization": 
auth_header}).json()

I dont understand why but the response is always an authentication error. When I do the same very code, for a GET request, it works:

consulta="user_trades"
book="eth_mxn"
limit="2"
nonce =  str(int(round(time.time() * 1000)))
http_method = "GET"
request_path = "/v3/"+consulta+"?"
json_payload={"book":book,"limit":limit}


# Create signature
message = nonce+http_method+request_path+urlencode(json_payload)
signature = hmac.new(bitso_secret.encode('utf-8'),
                                        message.encode('utf-8'),
                                        hashlib.sha256).hexdigest()
print(signature)
# Build the auth header
auth_header = 'Bitso %s:%s:%s' % (bitso_key, nonce, signature)
url="https://api.bitso.com"+request_path
print(url,message)
# Send request
response = requests.get(url, params=json_payload, headers={"Authorization": 
auth_header}).json()

I believe it's a problem with the variable "message", which is use to create the signature for the request, I don't know how to create it using the json_payload correctly.

edit: Written in python 3. The unsuccess response of the Request POST is:

{'error': {'code': '0201', 'message': 'Invalid Nonce or Invalid 
Credentials'}, 'success': False} 
1

There are 1 answers

2
vicco On

Use the following code:

import time
import hmac
import hashlib
import requests
import json
import random
import sys

def main(argv):
    # Bitso API url
    bitso_url = "https://api.bitso.com"
    # Obtained api and secret keys for handling private requests
    bitso_key = "<KEY>"
    bitso_secret = "<SECRET>"

    # A valid number to avoid replay attacks
    nonce = str(int(round(time.time())) * 100000 * 2)

    # Desired HTTP method
    http_method = "POST"
    request_path = "/api/v3/<POST_ENDPOINT>" 

    # The required info that endpoint requires to process info
    payload = {}
    #Add required keys of the parameters to the json
    #As follows
    #payload["<needed key>"] = <key value>

    #json encoding
    json_payload = json.dumps(payload)

    # Create secure signature with BITSO API documentation specification
    message = nonce + http_method + request_path + json_payload
    signature = hmac.new(bitso_secret.encode('utf-8'),
                        message.encode('utf-8'),
                        hashlib.sha256).hexdigest()

    # Build the auth header
    auth_header = 'Bitso %s:%s:%s' % (bitso_key, nonce, signature)

    # Send request
    response = requests.post(bitso_url+request_path,
        headers = {"Authorization" : auth_header},
        json = payload)

    print(response.content)

if __name__ == "__main__":
   main(sys.argv[1:])