Get your own Node server
const crypto = require('crypto');

// Data and keys
const data = 'Message to authenticate';
const key1 = 'secret-key-1';
const key2 = 'secret-key-2';

// Plain SHA-256 hash (no key)
function createHash(data) {
  const hash = crypto.createHash('sha256');
  hash.update(data);
  return hash.digest('hex');
}

// HMAC-SHA-256 (with key)
function createHmac(data, key) {
  const hmac = crypto.createHmac('sha256', key);
  hmac.update(data);
  return hmac.digest('hex');
}

// Compare results
console.log(`Data: "${data}"`);
console.log('\nPlain SHA-256 (no key):');
console.log(createHash(data));

console.log('\nHMAC-SHA-256 with key1:');
console.log(createHmac(data, key1));

console.log('\nHMAC-SHA-256 with key2:');
console.log(createHmac(data, key2));

// Demonstrate hash extension attack vulnerability
// This is a simplified illustration - actual extension attacks are more complex
console.log('\nHash Extension Attack Vulnerability:');

const originalData = 'original-message';
const originalHash = createHash(originalData);
console.log(`Original data: "${originalData}"`);
console.log(`Original SHA-256: ${originalHash}`);

// Attacker doesn't know the original data, but knows its hash
// and wants to append malicious data
const appendedData = 'malicious-appendage';
const combinedData = `${originalData}${appendedData}`;
const combinedHash = createHash(combinedData);
console.log(`Appended data: "${appendedData}"`);
console.log(`Combined data: "${combinedData}"`);
console.log(`Combined SHA-256: ${combinedHash}`);
console.log('With plain hash, an attacker who knows the hash of original data can compute valid hash for combined data without knowing the original data');

// HMAC is not vulnerable to extension attacks
console.log('\nHMAC Protection:');
const originalHmac = createHmac(originalData, key1);
const combinedHmac = createHmac(combinedData, key1);
console.log(`Original HMAC: ${originalHmac}`);
console.log(`Combined HMAC: ${combinedHmac}`);
console.log('With HMAC, an attacker cannot compute a valid HMAC for combined data without knowing the secret key');

              
Data: "Message to authenticate"

Plain SHA-256 (no key):
1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3

HMAC-SHA-256 with key1:
2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b34c5d

HMAC-SHA-256 with key2:
3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b34c5d6e

Hash Extension Attack Vulnerability:
Original data: "original-message"
Original SHA-256: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3
Appended data: "malicious-appendage"
Combined data: "original-messagemalicious-appendage"
Combined SHA-256: 3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b34c5d6e7f
With plain hash, an attacker who knows the hash of original data can compute valid hash for combined data without knowing the original data

HMAC Protection:
Original HMAC: 4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b34c5d6e7f8
Combined HMAC: 5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b34c5d6e7f89a
With HMAC, an attacker cannot compute a valid HMAC for combined data without knowing the secret key