I generate a pair public/private key on Client and send the publicKey
to the Server and the backend will generate a sharedKey
on its side and respond me a publicKey
which help me to generate a sharedKey
on the client too for encryption/decryption. So I encrypt a message by AES-256-GCM on Nodejs and decrypted the message on the Client.
Backend-Side:
export function encrypt(sharedKey: string, message: string) {
const firstIv = getRandomIV();
const cipher = crypto.createCipheriv(
'aes-256-gcm',
Buffer.from(sharedKey, 'base64'),
firstIv
);
const encrypted = cipher.update(message, 'utf8');
return Buffer.from(encrypted + cipher.final()).toString('base64');
}
function getRandomIV() {
return crypto.randomBytes(12);
}
Client-Side:
async function decrypt(encryptedData: Uint8Array) {
const aesKey = await generateAesKey();
const nonce = encryptedData.subarray(0, SERVER_ENCRYPTION_IV_LENGTH);
const data = encryptedData.subarray(SERVER_ENCRYPTION_IV_LENGTH);
const decrypted = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: nonce,
},
aesKey,
data
);
return {
decrypted: new Uint8Array(decrypted),
decryptedString: new TextDecoder().decode(decrypted),
};
}
async function generateAesKey() {
const publicKey = await getServerPublicKey();
const privateKey = await getPrivateKey();
const sharedSecret = await crypto.subtle.deriveBits(
{
name: 'ECDH',
public: publicKey!,
},
privateKey,
256
);
const aesSecret = await crypto.subtle.digest('SHA-256', sharedSecret);
return crypto.subtle.importKey('raw', aesSecret, 'AES-GCM', true, [
'encrypt',
'decrypt',
]);
}
Now, I can't decrypt the server encrypted response in the client and I encounter to DOMException
error and I don't know why?