简体   繁体   English

从“crypto”迁移到 crypto-js 库:二进制编码

[英]Migrating from 'crypto' to crypto-js library: Binary encoding

I'm trying to generate SHA256 and HmacSHA512 hashes on a device which unfortunately has no support for the standard Node crypto library.我正在尝试在不支持标准节点crypto库的设备上生成 SHA256 和 HmacSHA512 哈希值。 So I am adjusting the code to use CryptoJS instead.所以我正在调整代码以使用 CryptoJS。 However, CryptoJS cannot encode the Hash as in binary (only Hex, Base64 and Latin1 are available encoders).但是,CryptoJS 不能像二进制那样对哈希进行编码(只有 Hex、Base64 和 Latin1 是可用的编码器)。

Below is the function I'm trying to migrate.下面是我正在尝试迁移的功能。 Previous (unusable) code is commented out.以前(不可用)的代码被注释掉。

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

I found the answer.我找到了答案。 First of all: btoa() is not necessary, as CryptoJS has its own functionality to turn Base64 into its own format (WordLists): CryptoJS.enc.Base64.parse .首先: btoa()不是必需的,因为 CryptoJS 有自己的功能将 Base64 转换为自己的格式(WordLists): CryptoJS.enc.Base64.parse Next up is that path and hash_digest cannot be merged properly as there's a Type Mismatch (string and binary), so JS uses the string representation.接下来是pathhash_digest无法正确合并,因为存在类型不匹配(字符串和二进制),因此 JS 使用字符串表示。 The solution is to first create a SHA512 HMAC using CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret) and then update it step-by-step for each value with hmac.update(value, secret) .解决的办法是首先创建使用HMAC SHA512 CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret) ,然后更新它一步一步用于与每个值hmac.update(value, secret) Finally, you'll also have to use CryptoJS' built-in Base64 decoder to finally produce the signature string.最后,您还必须使用 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);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM