I've Encrypted my text by a key in Client by AES-256-GCM algorithm and I can decrypt it in Client, But when I send it to the Backend which has a SharedKey(the same as the Client has), it can decrypt the message by AES-256-CTR algorithm(I used this algo because the AES-256-GCM in Nodejs needs authTag that I don't create it in Client and iv is the only thing I have).
When I decrypt the message on the Backend side, it works with no error, but the result is not what I encrypted in the Client
Here is what I wrote: Client:
async function encrypt(text: string) {
const encodedText = new TextEncoder().encode(text);
const aesKey = await generateAesKey();
const iv = window.crypto.getRandomValues(
new Uint8Array(SERVER_ENCRYPTION_IV_LENGTH)
);
const encrypted = await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv,
},
aesKey,
encodedText
);
const concatenatedData = new Uint8Array(
iv.byteLength + encrypted.byteLength
);
concatenatedData.set(iv);
concatenatedData.set(new Uint8Array(encrypted), iv.byteLength);
return arrayBufferToBase64(concatenatedData),
}
Backend:
export function decrypt(sharedKey: string, message: string) {
const messageBuffer = new Uint8Array(base64ToArrayBuffer(message));
const iv = messageBuffer.subarray(0, 16);
const data = messageBuffer.subarray(16);
const decipher = crypto.createDecipheriv(
'aes-256-ctr',
Buffer.from(sharedKey, 'base64'),
iv
);
const decrypted =
decipher.update(data, 'binary', 'hex') + decipher.final('hex');
return Buffer.from(decrypted, 'hex').toString('base64');
}
Sample usage:
const encrypted = encrypt("Hi Everybody");
// send the encrypted message to the server
// Response is: Ô\tp\x8F\x03$\f\x91m\x8B B\x1CkQPQ=\x85\x97\x8AêsÌG0¸Ê