2

我正在尝试使用 WebCrypto 加密文本。我将结果转换为 utf8 字符串,然后将其转换为十六进制。加密/解密有效。但是,我想将数据转换为十六进制。当我尝试转换为十六进制并返回时,结果是不同的。

这是小提琴(使用 Chrome):https ://jsfiddle.net/yxp01v5g/

测试代码在这里:

var text = "hello world";
var key = App.crypto.generateKey(16);

App.crypto.encrypt(text, key, function(encryptedText, iv){
  console.log("encrypted text:", encryptedText, "iv", iv);

  var encryptedTextHex = convertUtf8StringToHex(encryptedText);
  console.log("encrypted text hex", encryptedTextHex);

  var backToUtf8 = convertHexToUtf8(encryptedTextHex);
  console.log("Back to utf8", backToUtf8);
  console.assert(encryptedText == backToUtf8);
})

如您所见,我正在获取结果,将其转换为十六进制,然后将其转换回 utf8,希望它与原始结果相同。然而,事实并非如此。

谁能告诉我到底我做错了什么?

4

1 回答 1

3

我没有深入研究小提琴中使用的调用链来进行转换,但它似乎尝试将 UTF-16/UCS-2 转换为字节大小,而不是缓冲区内容本身的实际十六进制表示。

这是将字节缓冲区内容转换为十六进制字符串表示形式,并将十六进制字符串转换回二进制数据的一种方法。

它获取缓冲区中的每个字节并生成其值的两位十六进制表示,并将其连接到字符串。

反向从字符串表示中获取两个字符并将其转换回字节值表示。

// some bytes as Uint8Array
var random = crypto.getRandomValues(new Uint8Array(16)), i, str = "", allOK = true;

// convert to HEX string representation
for(i = 0; i < random.length; i++) str += pad2(random[i].toString(16));
console.log(str);

// convert back to byte buffer
var buffer = new Uint8Array(random.length);
for(i = 0; i < buffer.length; i++) buffer[i] = parseInt(str.substr(i<<1, 2), 16);

// check if same content
for(i = 0; i < buffer.length; i++) if (buffer[i] !== random[i]) allOK = false;
console.log("All OK?", allOK)

function pad2(s) {return s.length < 2 ? "0" + s : s}; // helper: pad to 2 digits

于 2017-02-23T05:45:33.980 回答