从'crypto'迁移到crypto-js库:二进制编码 [英] Migrating from 'crypto' to crypto-js library: Binary encoding

查看:329
本文介绍了从'crypto'迁移到crypto-js库:二进制编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在不支持标准Node crypto 库的设备上生成SHA256和HmacSHA512哈希。因此,我正在调整代码以改为使用CryptoJS。但是,CryptoJS不能像二进制那样对哈希进行编码(只有十六进制,Base64和Latin1是可用的编码器)。

I'm trying to generate SHA256 and HmacSHA512 hashes on a device which unfortunately has no support for the standard Node crypto library. So I am adjusting the code to use CryptoJS instead. However, CryptoJS cannot encode the Hash as in binary (only Hex, Base64 and Latin1 are available encoders).

下面是我要迁移的函数。

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


推荐答案

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

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. 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. 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). Finally, you'll also have to use CryptoJS' built-in Base64 decoder to finally produce the signature string.

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

这篇关于从'crypto'迁移到crypto-js库:二进制编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆