如何在Windows Phone 8上创建此哈希

时间:2014-01-04 21:11:43

标签: c# hash windows-phone-8 cryptography windows-phone

我正在使用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;
}

但是当我到达加密部分时,由于缺少库,我会陷入困境。

1 个答案:

答案 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;
}