2

crypto我正在尝试在不支持标准节点库的设备上生成 SHA256 和 HmacSHA512 哈希。所以我正在调整代码以使用 CryptoJS。但是,CryptoJS 无法将哈希编码为二进制(只有 Hex、Base64 和 Latin1 是可用的编码器)。

以下是我要迁移的功能。以前的(不可用的)代码被注释掉了。

const getMessageSignature = (path, request, secret, nonce) => {
    // Expected outcome:
    // API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
    const message = JSON.stringify(request);

    const secret_buffer = btoa(secret);
    const hash = CryptoJS.algo.SHA256.create();
    const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secret_buffer);
    const hash_digest = hash.update(nonce + message).finalize().toString(CryptoJS.enc.Base64);
    const hmac_digest = hmac.update(path + hash_digest).finalize().toString(CryptoJS.enc.Base64);

    // CANNOT USE BELOW (Buffer and crypto not supported)
    // const secret_buffer = new Buffer(secret, 'base64');
    // const hash = new crypto.createHash('sha256');
    // const hmac = new crypto.createHmac('sha512', secret_buffer);
    // const hash_digest = hash.update(nonce + message).digest('binary');
    // const hmac_digest = hmac.update(path + hash_digest, 'binary').digest('base64');

    return hmac_digest;
};
4

1 回答 1

2

我找到了答案。首先:btoa()没有必要,因为 CryptoJS 有自己的功能可以将 Base64 转换为自己的格式(WordLists)CryptoJS.enc.Base64.parse:. 接下来是由于类型不匹配(字符串和二进制)pathhash_digest无法正确合并,因此 JS 使用字符串表示。解决方案是首先使用 SHA512 HMAC 创建一个 SHA512 HMAC CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret),然后使用 .为每个值逐步更新它hmac.update(value, secret)。最后,您还必须使用 CryptoJS 的内置 Base64 解码器来最终生成签名字符串。

const getMessageSignature = (path, request, secret, nonce) => {
    // API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
    const message = JSON.stringify(request);
    const hash = CryptoJS.SHA256(nonce + message);
    const secret_buffer = CryptoJS.enc.Base64.parse(secret);
    const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret_buffer);
    hmac.update(path, secret_buffer);
    hmac.update(hash, secret_buffer);
    return hmac.finalize().toString(CryptoJS.enc.Base64);
};
于 2018-09-27T08:38:53.537 回答