我正在构建一个程序,与加密货币交易所的 API 交互以下达买入/卖出订单等。
为了使用交易所的私有(private) API 方法,我必须在 http header 中包含一个标志,即 POST 消息正文,并使用 key 使用 HMACSHA512 进行加密。
下面的代码在我的系统中运行得很好,但我的一些用户报告说,当他们尝试使用某些私有(private) API 方法时,服务器总是返回签名错误。
我尝试在多个系统设置中重现该错误,但无济于事。
我想知道下面的代码的任何部分在不同的系统设置中使用时是否容易出现不一致。
public string SendQuery(string apiKey, string secretKey, string method, string[] param, string url)
{
// nonce
string nonceStr = Utility.CurrentTimeMillis().ToString() + "0000000000";
// generate the POST message
string postString = "method=" + method + "&nonce=" + nonceStr;
if (param != null)
{
foreach (string item in param) postString += "&" + item;
}
byte[] postData = Encoding.ASCII.GetBytes(postString);
// sign POST message
HMACSHA512 hMACSHA512 = new HMACSHA512(Encoding.ASCII.GetBytes(secretKey));
byte[] sign = hMACSHA512.ComputeHash(postData);
string signString = string.Empty;
for (int i = 0; i < sign.Length; i++)
{
signString += sign[i].ToString("X2");
}
signString = signString.ToLower(); // must use lower case
// generate headers
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add("Key", apiKey);
request.Headers.Add("Sign", signString);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
request.KeepAlive = true;
request.Proxy = null;
request.Method = "POST";
request.Timeout = 5000;
string message = string.Empty;
try
{
using (Stream st = request.GetRequestStream())
st.Write(postData, 0, postData.Length);
Stream responseStream = request.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(responseStream);
string line = "";
while (line != null)
{
line = objReader.ReadLine();
if (line != null) message += line;
}
}
catch (Exception ex)
{
}
return message;
}
最佳答案
所以回答我自己的问题,
事实证明,问题并不在于我的 SendQuery 方法中,而是调用它的函数使用 Double.ToString("F8") 来生成参数值,这会导致小数分隔符字符根据本地格式而变化。
例如:
double val = 1000.5;
string str = val.ToString("F8");
根据格式的不同,会产生 “1000.50000000”或 “1000,50000000”。
因此,在使用 Double.ToString 方法时,您必须提供 IFormatProvider 参数, 或者只是使用一个肮脏但有效的技巧,例如:
ToString("F8").Replace(",", ".");
关于C#.NET - 使用 HMAC-SHA512 签名 HTTP POST 消息在某些系统中会产生不一致的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48733839/