const crypto = require('crypto');
// Data to encrypt
const plainText = 'Secret message';
const associatedData = 'Additional data to authenticate';
// Generate key and IV (nonce)
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(12); // 12 bytes (96 bits) is recommended for GCM
// === ENCRYPTION ===
// Create cipher using AES-GCM
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
// Set the Additional Authenticated Data (AAD)
cipher.setAAD(Buffer.from(associatedData));
// Encrypt the data
let encrypted = cipher.update(plainText, 'utf8', 'hex');
encrypted += cipher.final('hex');
// Get the authentication tag
const authTag = cipher.getAuthTag();
console.log('Encrypted Text:', encrypted);
console.log('Auth Tag (hex):', authTag.toString('hex'));
console.log('Associated Data:', associatedData);
// === DECRYPTION ===
// Create decipher
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
// Set the same AAD
decipher.setAAD(Buffer.from(associatedData));
// Set the authentication tag
decipher.setAuthTag(authTag);
try {
// Decrypt
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log('Decrypted Text:', decrypted);
console.log('Decryption successful:', plainText === decrypted);
} catch (error) {
console.error('Decryption failed:', error.message);
}
// === DECRYPTION WITH WRONG AUTH TAG (will fail) ===
try {
const wrongDecipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
wrongDecipher.setAAD(Buffer.from(associatedData));
// Set a wrong authentication tag
const wrongAuthTag = crypto.randomBytes(16);
wrongDecipher.setAuthTag(wrongAuthTag);
// Try to decrypt
let wrongDecrypted = wrongDecipher.update(encrypted, 'hex', 'utf8');
wrongDecrypted += wrongDecipher.final('utf8'); // This will throw
console.log('Should not reach here');
} catch (error) {
console.error('Decryption with wrong auth tag failed (expected):', error.message);
}