Search code examples
stringtypescriptencryptionarraybuffer

Turning encrypted data into a string and back


I would like to store the encrypted data in a string format. Unfortunately I am not able to do that and I don't understand why.

For some reason this line:

const str = new TextEncoder().encode(buff1); 

creates a string with more bytes and different bytes then those in the Arraybuffer before.

The end result of this code is that these are logged to the console:
ArrayBuffer { byteLength: 139 }
ArrayBuffer { byteLength: 262 }

This is a problem since they should have been similar but they are not. I tried a lot of alternatives but all possible ways to do this end up with this same issue. I would really appreciate it if someone can tell me how to fix this.

Note that the EncryptText function works like it should. I only added it for those who would like to run the code into their IDE.

async function encryptText(plainText, iv, password): Promise<ArrayBuffer> {
    const ptUtf8 = new TextEncoder().encode(plainText);
    const pwUtf8 = new TextEncoder().encode(password);
    const pwHash = await crypto.subtle.digest('SHA-256', pwUtf8);
    const alg = { name: 'AES-GCM', iv: iv };
    const key = await crypto.subtle.importKey('raw', pwHash, alg, false, ['encrypt']);
    return crypto.subtle.encrypt(alg, key, ptUtf8);
};

async function encrBuffToUtf8Test() {
    const plainData = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' +
        'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.';
    const password = 'infamous';
    const randomValues = crypto.getRandomValues(new Uint8Array(12));

    const encryptionResult1 = await this.encryptText(plainData, randomValues, password);

    const buff1 = Buffer.from(encryptionResult1);
    const str = new TextEncoder().encode(buff1);
    const utf8buff = new TextDecoder('utf-8').decode(buff);
    const encryptionResult2 = utf8buff.buffer;
    const resTest = encryptionResult1 === encryptionResult2;
    if (!resTest) {
        console.log(encryptionResult1);
        console.log(encryptionResult2);
    }
}

Solution

  • I think I write this as an answer almost every day, but once again, you can't convert arbitrary binary data to a string using standard character encodings. It simply does not work that way.

    Consider using base64 or hex instead.