gpt4 book ai didi

vb.net - 这个 coinmex API 有什么问题?

转载 作者:行者123 更新时间:2023-12-02 00:54:31 25 4
gpt4 key购买 nike

Protected Overrides Function getJsonPrivate(method As String, otherParameters() As Tuple(Of String, String)) As String
Dim base = "https://www.coinmex.com"
Dim premethod = "/api/v1/spot/ccex/"
Dim longmethod = premethod + method

Dim timestampstring = getEstimatedTimeStamp().ToString

Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{}

Dim hasher = New System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(_secret1))
Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
Dim signature = System.Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

'_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
'_passphrase1= 1Us6&f%*K@Qsqr**
'
Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

Return response
End Function

Public Overrides Sub readbalances()
typicalReadBalances("account/assets", "data", "currencyCode", "available", "frozen", "", {})
End Sub

我想我是按照这里列出的那样做的 https://github.com/coinmex/coinmex-official-api-docs/blob/master/README_EN.md#1-access-account-information

# Request
GET /api/v1/spot/ccex/account/assets

# Response
[
{
"available":"0.1",
"balance":"0.1",
"currencyCode":"ETH",
"frozen":"0",
"id":1
},
{
"available":"1",
"balance":"1",
"currencyCode":"USDT",
"frozen":"0",
"id":1
}
]

并用于签名

这是说明书上说的

The ACCESS-SIGN header is the output generated by using HMAC SHA256 to create the HMAC SHA256 using the BASE64 decoding secret key in the prehash string to generate timestamp + method + requestPath + "?" + queryString + body (where ‘+’ represents the string concatenation) and BASE64 encoded output. The timestamp value is the same as the ACCESS-TIMESTAMP header. This body is the request body string or omitted if there is no request body (usually the GET request). This method should be capitalized.

Remember that before using it as the key to HMAC, base64 decoding (the result is 64 bytes) is first performed on the 64-bit alphanumeric password string. In addition, the digest output is base64 encoded before sending the header.

User submitted parameters must be signed except for sign. First, the string to be signed is ordered according to the parameter name (first compare the first letter of all parameter names, in alphabetic order, if you encounter the same first letter, then you move to the second letter, and so on).

For example, if we sign the following parameters

curl "https://www.coinmex.com/api/v1/spot/ccex/orders?limit=100"       

Timestamp = 1590000000.281
Method = "POST"
requestPath = "/api/v1/spot/ccex/orders"
queryString= "?limit=100"
body = {
'code': 'ct_usdt',
'side': 'buy',
'type': 'limit',
'size': '1',
'price': '1',
'funds': '',
}

Generate the string to be signed

Message = '1590000000.281GET/api/v1/spot/ccex/orders?limit=100{"code": "ct_usdt", "side": "buy", "type": "limit", "size": "1", "price": "0.1", "funds": ""}'

Then, the character to be signed is added with the private key parameters to generate the final character string to be signed.

For example:

hmac = hmac(secretkey, Message, SHA256)
Signature = base64.encode(hmac.digest())

我认为可能 _secret1 是一个 base64 字符串而不是 utf8,所以我改为

Dim base = "https://www.coinmex.com"
Dim premethod = "/api/v1/spot/ccex/"
Dim longmethod = premethod + method

Dim timestampstring = getEstimatedTimeStamp().ToString

'Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{} also doesn't work
Dim stringtosign = timestampstring + "GET" + longmethod '1553784499976GET/api/v1/spot/ccex/account/assets

Dim hasher = New System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(_secret1)) 'secret looks like 43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2
Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
Dim signature = Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

'_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
'_passphrase1= 1Us6&f%*K@Qsq***
'
Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

Return response

也不行。

秘钥(我截掉了几个字母)看起来像

43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2

这是应该解码为 base 64 或 utf8 还是什么的东西?

规范说它是 64。但是,它看起来不像 64 位编码的字符串。看起来字母来自 0-f

最佳答案将:1. 告诉我代码中出了什么问题。我做了改变。尝试。运行。作品。太棒了。

一个好的答案会2. 带有假/真实签名/随机数/密码短语和真实 header 和签名的示例模拟。这样我就可以看到我的错误结果到底在哪里。

更新:我再次修改了代码。我将时间戳更改为秒而不是毫秒。我删除了 {}。我两种方式都用。

    Dim base = "https://www.coinmex.com"
Dim premethod = "/api/v1/spot/ccex/"
Dim longmethod = premethod + method

Dim timestampstring = (getEstimatedTimeStamp() / 1000).ToString

Dim stringtosign = timestampstring + "GET" + longmethod '1555154812.857GET/api/v1/spot/ccex/account/assets

Dim hasher = New System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(_secret1)) '"43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac2******
Dim sighashbyte = hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringtosign))
Dim signature = Convert.ToBase64String(sighashbyte) '"FIgrJFDOQctqnkOTyuv6+uTy6xw3OZiP4waC1u6P5LU="=
Dim url = base + longmethod 'https://www.coinmex.com/api/v1/spot/ccex/account/assets

'_apiKey1="cmx-1027e54e4723b09810576f8e7a5413**"
'_passphrase1= 1Us6&f%*K@QsqrYZ
'
Dim response = CookieAwareWebClient.downloadString1(url, "", {Tuple.Create("ACCESS-KEY", _apiKey1), Tuple.Create("ACCESS-SIGN", signature), Tuple.Create("ACCESS-TIMESTAMP", timestampstring), Tuple.Create("ACCESS-PASSPHRASE", _passphrase1)})

Return response

还是不行。

当前错误是

消息 = "远程服务器返回错误:(401) 未授权。"

我很乐意提供一些只读的 API key 。不挂断。或者创建一个空帐户,然后拥有一个只读的 API key

最佳答案

文档说明

This body is the request body string or omitted if there is no request body (usually the GET request)

注意:强调我的

但是您在 GET 请求中包含了一个空的 JSON 对象

Dim stringtosign = timestampstring + "GET" + longmethod + "{}" '1553784499976GET/api/v1/spot/ccex/account/assets{}

{} 不应包含在 GET 请求中。

'1553784499976GET/api/v1/spot/ccex/account/assets
Dim stringtosign = timestampstring + "GET" + longmethod

看来您没有按照文档正确构建签名。

注意到文档

The root URL for REST access:https://www.coinmex.pro

当您尝试调用 "https://www.coinmex.com"

Timestamp

Unless otherwise specified, all timestamps in APIs are returned in microseconds.

The ACCESS-TIMESTAMP header must be the number of seconds since UTC's time Unix Epoch. Decimal values are allowed. Your timestamp must be within 30 seconds of the API service time, otherwise your request will be considered expired and rejected. If you think there is a large time difference between your server and the API server, then we recommend that you use the time point to check the API server time.

注意:强调我的

使用以下扩展方法计算时间戳

private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

/// <summary>
/// Converts the value of the current <see cref="System.DateTime"/> object to Unix Time.
/// </summary>
/// <param name="dateTime"></param>
/// <remarks>
/// </remarks>
/// This method first converts the current instance to UTC before returning its Unix time.
/// <returns>
/// A <see cref="System.Int64"/> defined as the number of seconds that have elapsed since midnight Coordinated Universal Time (UTC), January 1, 1970, not counting leap seconds.
/// </returns>
public static long ToUnixTimeSeconds(this DateTime dateTime) {
if (dateTime.ToUniversalTime() < Epoch) {
return 0;
}

var totalSeconds = dateTime.ToUniversalTime().Subtract(Epoch).TotalSeconds;
var timestamp = Convert.ToInt64(totalSeconds);

return timestamp;
}

我做了以下测试,看看我是否可以按照文档调用 API,它似乎有效。

不过我用的是c#

[TestClass]
public class CoinMaxAPITests {
const string apiKey1 = "cmx-1027e54e4723b09810576f8e7a5413**";
const string fakeSecret = "43a90185f5b7ab25af045e9e64bac5dc745934f359f1806fcdd2a4af80ac23==";
const string passphrase1 = "1Us6&f%*K@QsqrYZ";

Lazy<HttpClient> http = new Lazy<HttpClient>(() => {
var rootUrl = "https://www.coinmex.pro";

CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler {
CookieContainer = cookies,
UseCookies = true,

};
var client = new HttpClient() {
BaseAddress = new Uri(rootUrl)
};
client.DefaultRequestHeaders.TryAddWithoutValidation("ACCESS-KEY", apiKey1);
client.DefaultRequestHeaders.TryAddWithoutValidation("ACCESS-PASSPHRASE", passphrase1);
return client;
});

[TestMethod]
public async Task Should_Accept_Signature() {
//Arrange
var requestPath = "/api/v1/spot/public/time";
var method = "GET";
var timeStamp = getEstimatedTimeStamp().ToString(); //"1555253371"

var message = timeStamp + method + requestPath; //"1555253371GET/api/v1/spot/public/time"

var secretKey = Convert.FromBase64String(fakeSecret);
var hmac = new HMACSHA256(secretKey);
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
var signature = Convert.ToBase64String(hash);//Jzui/eO3iyLTD6L9qVkUO0EBpZP/lFhx1HlsbuSNt/8=

var request = new HttpRequestMessage(HttpMethod.Get, requestPath);
request.Headers.TryAddWithoutValidation("ACCESS-TIMESTAMP", timeStamp);
request.Headers.TryAddWithoutValidation("ACCESS-SIGN", signature);

//Act
var response = await http.Value.SendAsync(request);

//Assert
response.EnsureSuccessStatusCode();

var json = await response.Content.ReadAsStringAsync();
//"{\"epoch\":\"1555253501.225\",\"iso\":\"2019-04-14T14:51:41.225Z\",\"timestamp\":1555253501225}"
var server = JsonConvert.DeserializeObject<ServerTime>(json);

server.Should().NotBeNull();
server.Iso.Date.Should().Be(DateTime.Today);
}

long getEstimatedTimeStamp() {
return DateTime.Now.ToUnixTimeSeconds(); //custom extension method
}
}


public partial class ServerTime {
[JsonProperty("epoch")]
public string Epoch { get; set; }

[JsonProperty("iso")]
public DateTime Iso { get; set; }

[JsonProperty("timestamp")]
public long Timestamp { get; set; }
}

并且能够获得调用 /api/v1/spot/public/time 的有效 JSON 响应,即使使用假 key ,我也能够反序列化我的断言。可能因为这是公共(public) API。这确实证明调用的 URL 是正确的。

当请求路径更改为

"/api/v1/spot/ccex/account/assets"

并测试了来自 API 的更安全的私有(private)数据,响应为 400 Bad Request,响应正文中包含以下内容

{"message":"Encrypted key does not exist"}

考虑到我使用的 key 是假的,这符合预期。

如果您遵循链接文档中的建议,这表明该 API 实际上确实按预期工作。

关于vb.net - 这个 coinmex API 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55404704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com