我正在构建一个与加密货币交易所API进行交互的程序,以便进行买入/卖出订单等。
为了使用交换机的私有API方法,我必须在http标头中加入一个标志,即POST消息体,使用密钥用HMACSHA512加密。
下面的代码在我的系统中完全正常,但我的一些用户报告说,当服务器尝试使用某些私有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;
}
答案 0 :(得分:0)
回答我自己的问题,
事实证明问题不在于我的SendQuery方法,但是调用它的函数使用Double.ToString(“F8”)来生成参数值,这会导致根据本地格式变化小数分隔符。
例如:
double val = 1000.5;
string str = val.ToString("F8");
取决于格式化将产生 “1000.50000000”或 “1000,50000000”。
因此,在使用Double.ToString方法时必须提供IFormatProvider参数, 或者只是使用像工作一样的肮脏但像工作一样的魅力:
ToString("F8").Replace(",", ".");