I have the following represented as an ArrayBuffer:
const encryptedMsg = await crypto.subtle.encrypt(algorithm, key, messageUTF8)
The byte length of this value is 28:
encryptedMsg
// ArrayBuffer { byteLength: 28 }
When I convert this into a Uint8Array then I get the following values:
const encryptedMsgArr = new Uint8Array(encryptedMsg)
// Uint8Array(28) [ 237, 243, 213, 127, 248, 55, 37, 237, 209, 21, … ]
I want to convert this into a UTF-8 cyphertext with a standard decoder and later revert that with a standard encoder:
const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8");
When decoding it:
const cypherText = decoder.decode(encryptedMsgArr)
"���\u007f�7%��\u0015\u00113\u0012\u0016�۹o׀.:+=��\u0015\u0015"
But when I try to encode it back into a Uint8Array then it doesn't match up even though utf-8 encoding was specified for both.
In fact the above doesn't even look like it's utf-8, and the byte length does not match up either (now 46 instead of 28):
encoder.encode(cypherText)
// Uint8Array(46) [ 239, 191, 189, 239, 191, 189, 239, 191, 189, 127, … ]
What am I doing wrong here?
Goal
To be able to export the cyphertext so it can be decrypted elsewhere at a later stage. If UTF-8 decoding of the ArrayBuffer doesn't work, the only other thing I can think of is to convert the AB into a stringified version of the array of integers and export that string, but I don't think that is a very sane methodology.
Edit
Actually, just declaring the encoder and decoder without utf-8 encoding fixes the issue, but @ornic has provided a nice base64 encoding/decoding function to use instead.
const encoder = new TextEncoder();
const decoder = new TextDecoder();