我正在使用Kraken API并查询我需要将哈希作为参数发送的私有方法。这就是他们的文档所说的:
公共方法可以使用GET或POST。
私有方法必须使用POST并按如下方式设置:
HTTP标头:
API-Key = API密钥
API-Sign =使用HMAC-SHA512的消息签名 (URI路径+ SHA256(nonce + POST数据))和base64解码的秘密API 关键
POST数据:
nonce =总是增加无符号64位整数
otp =双因素 密码(如果启用了双因素,否则不需要)
注意:那里 无法将nonce重置为较低的值,因此请务必使用a nonce生成方法,不会生成小于的数字 以前的现时。持续计数器或当前时间百分之一 建议使用第二精度或更高精度。
他们还有一个PHP / Node.JS / Python示例,用于创建API-Sign哈希。我试图将此代码移植到Windows Phone 8的C#,但我遇到了一个大问题:HMACSHA512类不适用于Windows Phone。我试图寻找可以创建HMAC-SHA512哈希的替代品,但找不到多少。 HashLib不适用于Windows Phone。 CryptSharp是,但我无法弄清楚如何添加消息和密码,如PHP的hash_hmac()函数允许。我也去寻找HMAC-SHA512算法的算法/伪代码来实现我自己的类,但奇怪的是我找不到它(它有另一个名字吗?)。
长话短说,我需要在兼容Windows Phone 8的代码中转换此代码,以产生相同的结果:
if(!isset($request['nonce'])) {
// generate a 64 bit nonce using a timestamp at microsecond resolution
// string functions are used to avoid problems on 32 bit systems
$nonce = explode(' ', microtime());
$request['nonce'] = $nonce[1] . str_pad(substr($nonce[0], 2, 6), 6, '0');
}
// build the POST data string
$postdata = http_build_query($request, '', '&');
// set API key and sign the message
$path = '/' . $this->version . '/private/' . $method;
$sign = hash_hmac('sha512', $path . hash('sha256', $request['nonce'] . $postdata, true), base64_decode($this->secret), true);
$headers = array(
'API-Key: ' . $this->key,
'API-Sign: ' . base64_encode($sign)
);
第一部分(直到$ sign = ...)看起来很简单:
long nonce = DateTime.UtcNow.Ticks;
string postData = "nonce=" + nonce;
if (!string.IsNullOrEmpty(otp))
{
postData += "&otp=" + otp;
}
但是当我到达加密部分时,由于缺少库,我会陷入困境。
答案 0 :(得分:-1)
这甚至不可能编译,但它应该给你一般的想法..
byte[] uriPath = GetBytes(uriPathString);
byte[] nonceAndPostData = GetBytes(nonce + postData);
byte[] keyData = Convert.FromBase64String(apiKey);
string decodedKey = Encoding.UTF8.GetString(keyData);
byte[] result;
SHA512 shaM = new SHA512Managed();
SHA256 shaN = new SHA256Managed();
result = shaN.ComputeHash(nonceAndPostData);
result = shaM.ComputeHash(result + decodedKey);
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}