如何将二进制字符串传递给 `btoa` 以对原始值进行编码

How to pass a binary string to `btoa` to encode the raw value

我需要修改此(工作)代码并用原生 JS 替换 CryptoJS 函数。

变量 b64encoded 具有正确的值,但我对本机代码 (encodedIncorrect) 的尝试却不正确。你能帮忙输入 btoa 正确的输入吗?

工作正常,但第 3 方库不能在我开发的平台上使用:

const encrypted = CryptoJS.HmacSHA1("message", "secret");
// encrypted = "0caf649feee4953d87bf903ac1176c45e028df16" << Hexadecimal encoded string
const b64encoded = CryptoJS.enc.Base64.stringify(encrypted);
// b64encoded = "DK9kn+7klT2Hv5A6wRdsReAo3xY="

不工作,特别是 btoa:

对二进制字符串的编码
const encrypted_vendor = VENDOR.hmacSHA1("message", "secret") // Vendor-provided HMAC-SHA1 func
// encrypted_vendor = "0caf649feee4953d87bf903ac1176c45e028df16"

// Split hex string into two-character byte representations for binary conversion
function splitHex(hexString) {
    let chunks = [];
    for (var i = 0, charsLength = hexString.length; i < charsLength; i += 2) {
        chunks.push(hexString.substring(i, i + 2));
    }
}
// Convert hex characters to binary value
function hexCharToBinary(value) {
    return (parseInt(value, 16).toString(2)).padStart(8, '0');
}

binaryChunks = splitHex(encrypted)
var binaryStr = ""
binaryChunks.forEach(i => binaryStr += hexCharToBinary(i))
// binaryStr = "0000110010101111011001001001111111101110111001001001010100111101100001111011111110010000001110101100000100010111011011000100010111100000001010001101111100010110"
encodedIncorrect = btoa(binaryStr)
// encodedIncorrect = "MDAwMDExMDAxMDEwMTExMTAxMTAwMTAwMTAwMTExMTExMTEwMTExMDExMTAwMTAwMTAwMTAxMDEwMDExMTEwMTEwMDAwMTExMTAxMTExMTExMDAxMDAwMDAwMTExMDEwMTEwMDAwMDEwMDAxMDExMTAxMTAxMTAwMDEwMDAxMDExMTEwMDAwMDAwMTAxMDAwMTEwMTExMTEwMDAxMDExMA=="

我还使用此站点 (https://cryptii.com/pipes/binary-to-base64) 验证了二进制输出是正确的,当设置为二进制输入时,它会将其编码为正确的 base64。

您编码的是二进制数字的字符串表示,而不是实际数据。

你需要一个binary string, which you can construct e.g. using String.fromCharCode:

const hexString = "0caf649feee4953d87bf903ac1176c45e028df16"

// split into two character groups (one byte each), see e.g.
// 
// using /.{1,2}/g may be preferrable for potential error handling
// but if there is always an even amount of characters, it doesn't matter.
let hexCharacterPairs = hexString.match(/../g);

// parse two hex characters as number
let bytes = hexCharacterPairs.map(e => parseInt(e, 16));

// generate symbols from the bytes
let binaryStringSymbols = bytes.map(e => String.fromCharCode(e));

// get a string from all the symbols
let binaryString = binaryStringSymbols.join("");

// use the binary string to get a base64 encode
let base64 = btoa(binaryString);

console.log(base64);

// or in one line
console.log(btoa("0caf649feee4953d87bf903ac1176c45e028df16".match(/../g).map(e => String.fromCharCode(parseInt(e, 16))).join("")));

请注意,上面的代码片段没有错误处理,例如对于输入中的奇数字符、无效字符等