e2ee-chat
Version:
A simple realtime chat SDK for web and mobile apps using socket.io with support for end-to-end encryption and multi-tenant backend integration.
84 lines (68 loc) • 2.55 kB
JavaScript
const CryptoJS = require("crypto-js");
function encryptMessage(message, secretKey) {
try {
// Match Flutter's encryption approach:
// 1. Use the secret key directly as Flutter does
const key = CryptoJS.enc.Utf8.parse(secretKey);
// 2. Generate SHA-256 hash like Flutter does: sha256.convert(keyBytes.bytes).bytes
const hashedKey = CryptoJS.SHA256(key);
// 3. Flutter uses IV.fromLength(16) - this creates a zero IV in the package
// Based on Flutter's encrypt package behavior with same IV
const iv = CryptoJS.lib.WordArray.create([0, 0, 0, 0]); // 16 bytes of zeros
// 4. Encrypt using AES-256-CBC
const encrypted = CryptoJS.AES.encrypt(message, hashedKey, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
// 5. Return base64 encoded string (matching Flutter's .base64 output)
return encrypted.toString();
} catch (e) {
console.error("Error encrypting message:", e);
throw e;
}
}
function decryptMessage(encryptedText, secretKey) {
try {
// Match Flutter's decryption approach:
// 1. Use the secret key directly as Flutter does
const key = CryptoJS.enc.Utf8.parse(secretKey);
// 2. Generate SHA-256 hash like Flutter does
const hashedKey = CryptoJS.SHA256(key);
// 3. Use the same IV as encryption
const iv = CryptoJS.lib.WordArray.create([0, 0, 0, 0]); // 16 bytes of zeros
// 4. Decrypt the base64 encrypted text
const decrypted = CryptoJS.AES.decrypt(encryptedText, hashedKey, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
// 5. Convert back to UTF-8 string
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
if (!decryptedText) {
throw new Error("Failed to decrypt message - invalid result");
}
return decryptedText;
} catch (e) {
console.error("Error decrypting message:", e);
console.error("Encrypted text was:", encryptedText);
console.error("Secret key was:", secretKey);
// Let's try alternative approaches for debugging
try {
// Try the old simple method as fallback
const bytes = CryptoJS.AES.decrypt(encryptedText, secretKey);
const result = bytes.toString(CryptoJS.enc.Utf8);
if (result) {
console.log("Fallback decryption worked");
return result;
}
} catch (fallbackError) {
console.error("Fallback decryption also failed:", fallbackError);
}
throw e;
}
}
module.exports = {
encryptMessage,
decryptMessage,
};