Javascript Kraken.com API:在AngularJS中生成消息签名

Javascript Kraken.com API:在AngularJS中生成消息签名,javascript,angular,encoding,cryptography,cryptojs,Javascript,Angular,Encoding,Cryptography,Cryptojs,我正在尝试学习Angular2,作为第一个练习,我想从Kraken.com API检索数据。(我知道,我本可以选择更简单的:) 嗯,对于“公众”电话来说,它很好用。现在我尝试调用“Private”方法。(那些需要认证) 正如这里所说: 预期签名为: API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

我正在尝试学习Angular2,作为第一个练习,我想从Kraken.com API检索数据。(我知道,我本可以选择更简单的:)

嗯,对于“公众”电话来说,它很好用。现在我尝试调用“Private”方法。(那些需要认证)

正如这里所说:

预期签名为:

API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
所以我正试图产生这个。。。没有成功。。。我经常收到以下错误消息:

Kraken API returned an error: API:Invalid nonce
但我很确定我的nonce是正确的,所以我宁愿认为它与数据加密有关

我已经找到了一个可以完成这项工作的函数,但我不能在我的角度项目中“按原样”使用它

/**
 * This method returns a signature for a request as a Base64-encoded string
 * @param  {String}  path    The relative URL path for the request
 * @param  {Object}  request The POST body
 * @param  {Integer} nonce   A unique, incrementing integer
 * @return {String}          The request signature
 */
function getMessageSignature(path, request, nonce) {
    var message = querystring.stringify(request);
    var secret  = new Buffer(config.secret, 'base64');
    var hash    = new crypto.createHash('sha256');
    var hmac    = new crypto.createHmac('sha512', secret);

    var hash_digest = hash.update(nonce + message).digest('binary');
    var hmac_digest = hmac.update(path + hash_digest, 'binary').digest('base64');

    return hmac_digest;
}
这是我的代码:

private getMessageSignature(path: string, request: any, nonce: number) {
    //API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

    var message = this.querystring.stringify(request);
    var secret  = this.CryptoJS.enc.Base64.parse(this.config.secret);
    var hash_digest = this.CryptoJS.SHA256(nonce + message);
    var hmac    = this.CryptoJS.HmacSHA512(path + hash_digest, secret).toString(this.CryptoJS.enc.Base64);
    return hmac;
}

问题可能是
path+hash_digest
,这是一种类型不匹配,会导致奇怪的结果,因为
hash_digest
将采用十六进制编码,而不会在其二进制表示中使用

以下措施可能有效:

var hmac = this.CryptoJS.HmacSHA512(path + hash_digest.toString(this.CryptoJS.enc.Latin1), secret).toString(this.CryptoJS.enc.Base64);
但以下是一个更好的选择:

var hmacHasher = this.CryptoJS.algo.HMAC.create(this.CryptoJS.algo.SHA512, secret);
hmacHasher.update(path);
hmacHasher.update(hash_digest);
var hmac = hmacHasher.finalize().toString(this.CryptoJS.enc.Base64);

问题可能是
path+hash_digest
,这是一种类型不匹配,会导致奇怪的结果,因为
hash_digest
将采用十六进制编码,而不会在其二进制表示中使用

以下措施可能有效:

var hmac = this.CryptoJS.HmacSHA512(path + hash_digest.toString(this.CryptoJS.enc.Latin1), secret).toString(this.CryptoJS.enc.Base64);
但以下是一个更好的选择:

var hmacHasher = this.CryptoJS.algo.HMAC.create(this.CryptoJS.algo.SHA512, secret);
hmacHasher.update(path);
hmacHasher.update(hash_digest);
var hmac = hmacHasher.finalize().toString(this.CryptoJS.enc.Base64);

哎哟!多亏了你的帮助,我终于成功地调用了我的API

在实际显示代码之前,我必须更改一些内容: 在我的查询中,我将参数传递为

application/x-www-form-urlencoded
发送的实际数据与用于计算签名的数据之间存在不匹配。 因此,我必须纠正这一点,以便在我的请求正文中发送的数据与签名计算中使用的数据完全相同:

let paramsStr = this.querystring.stringify(params);
好的,最后,这里是计算签名的代码:

private getMessageSignature(path: string, request: any, nonce: number) {
        //API-Sign = Message signature using HMAC-SHA512 of 
        // (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

        var message = this.querystring.stringify(request);
        var secret = this.CryptoJS.enc.Base64.parse(this.config.secret);
         var hash256 = this.CryptoJS.algo.SHA256.create();
        hash256.update(String(nonce));
        hash256.update(message);

        var hmacHasher = this.CryptoJS.algo.HMAC.create(this.CryptoJS.algo.SHA512, secret);
        hmacHasher.update(path);
        hmacHasher.update(hash256.finalize());

        var hashInBase64 = this.CryptoJS.enc.Base64.stringify(hmacHasher.finalize());
        return hashInBase64;
    }

哎哟!多亏了你的帮助,我终于成功地调用了我的API

在实际显示代码之前,我必须更改一些内容: 在我的查询中,我将参数传递为

application/x-www-form-urlencoded
发送的实际数据与用于计算签名的数据之间存在不匹配。 因此,我必须纠正这一点,以便在我的请求正文中发送的数据与签名计算中使用的数据完全相同:

let paramsStr = this.querystring.stringify(params);
好的,最后,这里是计算签名的代码:

private getMessageSignature(path: string, request: any, nonce: number) {
        //API-Sign = Message signature using HMAC-SHA512 of 
        // (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key

        var message = this.querystring.stringify(request);
        var secret = this.CryptoJS.enc.Base64.parse(this.config.secret);
         var hash256 = this.CryptoJS.algo.SHA256.create();
        hash256.update(String(nonce));
        hash256.update(message);

        var hmacHasher = this.CryptoJS.algo.HMAC.create(this.CryptoJS.algo.SHA512, secret);
        hmacHasher.update(path);
        hmacHasher.update(hash256.finalize());

        var hashInBase64 = this.CryptoJS.enc.Base64.stringify(hmacHasher.finalize());
        return hashInBase64;
    }

你确定路径和请求被正确编码了吗?Arf,我的评论被截断了,我甚至不能回答我自己的线程。这是我的原始回复(带有我的更新代码)谢谢Artjom!不,好主意。我还没看过Kraken Api你确定路径和请求的编码正确吗?Arf,我的评论被截断了,我甚至不能回答我自己的线程。这是我的原始回复(带有我的更新代码)谢谢Artjom!不,好主意。我没有看过Kraken Apike,它没有创建与问题中提供的函数相同的签名,它没有创建与问题中提供的函数相同的签名