Search code examples
c#apisignaturehmac

Invalid signature with Bittrex API calls in C#


I am trying to access my wallet balances in Bittrex via Bittrex's API calls, but for some reason I'm getting response message saying INVALID_SIGNATURE.

I use these functions to create the signature:

GetNonce

private String GetNonce()
{
    long ms = (long)((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);

    return ms.ToString();
}

GetApiSignature

private String GetApiSignature(String key, String message)
{
    using (var hmacsha512 = new HMACSHA512(Encoding.UTF8.GetBytes(key)))
    {
        hmacsha512.ComputeHash(Encoding.UTF8.GetBytes(message));
        return string.Concat(hmacsha512.Hash.Select(b => b.ToString("x2")).ToArray());
    }       
}

Here's how I "compile" my calls:

public String ApiQuery(String requestUrl)
{

    url = new Uri(requestUrl);
    webreq = WebRequest.Create(url);

    signature = GetApiSignature(apiSecret, requestUrl);
    webreq.Headers.Add("apisign", signature );

    webresp = webreq.GetResponse();
    stream = webresp.GetResponseStream();
    strRead = new StreamReader(stream);

    String rtn = strRead.ReadToEnd();

    return rtn;
}

I am getting a the same signature as the python API wrapper does with the same url and nonce etc., but cannot access my balances. When I do a call that doesn't require any signatures, it works just fine... Not sure at all what I'm doing wrong with this.


Solution

  • Got the answer from elsewhere. Looks like my encoding was wrong, and it didn't work because of that (though I thought I tried other encoders...).

    The correct encoding is ASCII, whereas I used UTF-8.

    Here's the function I got:

    private string genHMAC(string secret, string url)
    {
        var hmac = new HMACSHA512(Encoding.ASCII.GetBytes(secret));
        var messagebyte = Encoding.ASCII.GetBytes(url);
        var hashmessage = hmac.ComputeHash(messagebyte);
        var sign = BitConverter.ToString(hashmessage).Replace("-", "");
    
        return sign;
    }
    

    The problem is now solved and everything works as it should. :-)