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

// Create DiffieHellman instances for Alice and Bob
const alice = crypto.createDiffieHellman(2048);
alice.generateKeys();

// Bob uses Alice's parameters
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
bob.generateKeys();

// Exchange public keys
const alicePublicKey = alice.getPublicKey();
const bobPublicKey = bob.getPublicKey();

// Compute shared secrets
const aliceSecret = alice.computeSecret(bobPublicKey);
const bobSecret = bob.computeSecret(alicePublicKey);

// Use the shared secret as a key for encryption
// First, derive a suitable key using a hash function
function deriveKey(secret, salt, keyLength) {
  return crypto.pbkdf2Sync(secret, salt, 1000, keyLength, 'sha256');
}

// Alice sends an encrypted message to Bob
function encrypt(text, secret) {
  // Create a salt and derive a key
  const salt = crypto.randomBytes(16);
  const key = deriveKey(secret, salt, 32); // 32 bytes for AES-256
  const iv = crypto.randomBytes(16);
  
  // Encrypt the message
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  
  // Return everything Bob needs to decrypt
  return {
    salt: salt.toString('hex'),
    iv: iv.toString('hex'),
    encrypted
  };
}

// Bob decrypts the message from Alice
function decrypt(encryptedInfo, secret) {
  // Parse values
  const salt = Buffer.from(encryptedInfo.salt, 'hex');
  const iv = Buffer.from(encryptedInfo.iv, 'hex');
  const encrypted = encryptedInfo.encrypted;
  
  // Derive the same key
  const key = deriveKey(secret, salt, 32);
  
  // Decrypt the message
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  
  return decrypted;
}

// Alice encrypts a message using the shared secret
const message = 'Hello Bob, this is a secret message from Alice!';
console.log('Original message:', message);

const encryptedMessage = encrypt(message, aliceSecret);
console.log('Encrypted message:', JSON.stringify(encryptedMessage, null, 2));

// Bob decrypts the message using his shared secret
const decryptedMessage = decrypt(encryptedMessage, bobSecret);
console.log('Decrypted message:', decryptedMessage);

// Verify the shared secrets match
console.log('Shared secrets match:', aliceSecret.equals(bobSecret));

              
Original message: Hello Bob, this is a secret message from Alice!
Encrypted message: {
  "salt": "a1b2c3d4e5f67890",
  "iv": "1234567890abcdef1234567890abcdef",
  "encrypted": "f7a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2f4a6b8cadae1f3a5b7c9dbe0f2a4"
}
Decrypted message: Hello Bob, this is a secret message from Alice!
Shared secrets match: true