从'crypto'迁移到crypto-js库:二进制编码 [英] Migrating from 'crypto' to crypto-js library: Binary encoding
问题描述
我正在尝试在不支持标准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屋!