Ошибка подписи Binance API HMAC SHA256 с использованием C #

Пробую подключиться к Binance Api с помощью C# и RestSharp lib. На основе документы, я должен попробовать что-то вроде этого:

queryString: symbol = LTCBTC & side = BUY & type = LIMIT & timeInForce = GTC & amount = 1 & price = 0.1 & recvWindow = 5000 & timestamp = 1499827319559

Подпись HMAC SHA256:

[linux] $ echo -n "symbol = LTCBTC & side = BUY & type = LIMIT & timeInForce = GTC & amount = 1 & price = 0.1 & recvWindow = 5000 & timestamp = 1499827319559" | openssl dgst -sha256 -hmac "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j" (stdin) = c8db56825aefac0j0j ":

(HMAC SHA256) [linux] $ curl -H "X-MBX-APIKEY: vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A" -X POSTy6utIco14y7Ju91duEh8A "-X POSTSyntity&href=api == ПРЕДЕЛ & timeInForce = GTC и количество = 1 & цена = 0,1 & recvWindow = 5000 & метка = 1499827319559 & подпись = c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71" отн = "NOFOLLOW noreferrer"> https://api.binance.com/api/v3/order?symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price= 0.1 & recvWindow = 5000 & timestamp = 1499827319559 & signature = c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71

Я пробую много способов и много вопросов о стеке, но нашел решения для других языков, а не для C #. это я сделал на основе: this и это

public string GetAccountInfo()
    {
        long timeStamp = GetTimestamp();
        var request = new RestRequest("api/v3/account");
        request.AddHeader("X-MBX-APIKEY", ApiKey);
        request.AddParameter("timestamp", timeStamp, ParameterType.QueryString);
        request.AddParameter("recvWindow", RecvWindow, ParameterType.QueryString);
        request.AddParameter("signature", GetSignature(request.Parameters), ParameterType.QueryString);
        return Client.Get(request).Content;
    }
private long GetTimestamp()
    {
        return new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
    }

    private string GetSignature(List<Parameter> parameters)
    {
        var signature = "";
        if(parameters.Count > 0)
        {
            foreach (var item in parameters)
            {
                if(item.Name != "X-MBX-APIKEY")
                    signature += $"{item.Name}={item.Value}&";
            }
            signature = signature.Substring(0, signature.Length - 2);
        }
        byte[] keyBytes = Encoding.Unicode.GetBytes(ApiSecret);
        byte[] valueBytes = Encoding.Unicode.GetBytes(signature);
        return HashEncode(HashHMAC(keyBytes, valueBytes));
    }

    private static byte[] HashHMAC(byte[] key, byte[] message)
    {
        var hash = new HMACSHA256(key);
        return hash.ComputeHash(message);
    }

    private static string HashEncode(byte[] hash)
    {
        return BitConverter.ToString(hash).Replace("-", "").ToLower();
    }

но я получил эту ошибку: Подпись для этого запроса недействительна. Как я могу это исправить? Спасибо.


person Sadeq Shajary    schedule 28.03.2020    source источник
comment
Обычно такие ошибки требуют другого режима заполнения. Заполнение библиотеки Net по умолчанию отличается от значения по умолчанию в JSON. Также много проблем возникало с шифрованием в Net 4.7. Когда люди обновлялись из более старой сети, код переставал работать. Я думаю, что режимы шифрования по умолчанию в сети изменились, чтобы быть совместимыми с последними режимами шифрования.   -  person jdweng    schedule 28.03.2020
comment
Не знаю, почему именно, но я попробовал другой способ и получил правильный ответ. смотри мой ответ @jdweng   -  person Sadeq Shajary    schedule 28.03.2020
comment
Этот ответ решает мою проблему: https://stackoverflow.com/a/47686794   -  person Sadeq Shajary    schedule 28.03.2020


Ответы (1)


Ниже представлен рабочий пример генерации подписи:

    public static string CreateSignature(string queryString, string secret)
    {

        byte[] keyBytes = Encoding.UTF8.GetBytes(secret);
        byte[] queryStringBytes = Encoding.UTF8.GetBytes(queryString);
        HMACSHA256 hmacsha256 = new HMACSHA256(keyBytes);

        byte[] bytes = hmacsha256.ComputeHash(queryStringBytes);

        return BitConverter.ToString(bytes).Replace("-", "").ToLower();
    }

queryString - это ваша строка параметров, переданных в запросе, например. timestamp=1586620030079
secret - это ваш секрет API.

Важно отметить, что при пошаговой отладке запрос завершается с ошибкой Bad Request, поскольку метка времени выходит за пределы окна recv.

Вы также можете найти этот SDK очень полезным, по крайней мере, в качестве примера рабочего кода: https://github.com/nathan-alexander/csharp-binance-api.

person xalien    schedule 11.04.2020
comment
Просто использовал это в моем собственном API. Спасибо за это - person Caleb; 19.06.2021