4
votes

This is the nodejs documentation example:

const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');

// Note: This is a shortcut way to specify one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
  crypto.createHash('sha256').update('alice', 'utf8').digest()
);

// Bob uses a newly generated cryptographically strong
// pseudorandom key pair bob.generateKeys();

const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

// alice_secret and bob_secret should be the same shared secret value
console.log(alice_secret === bob_secret);

I don't understand where the secret comes in. Suppose I want to decrypt a message foo-bar from Bob (encrypted with Alice public key). I have Alice's private and public key, and Bob's encrypted message how can I decrypt the message having all this?

1

1 Answers

4
votes

The steps above constitute the ECDH key agreement protocol to establish a shared secret (a symmetric key) between Alice and Bob which they can subsequently use to communicate securely.

The secret key alice_secret is computed using Alice's private key and Bob's public key at Alice's end.
The key bob_secret is computed using Bob's private key and Alice's public key at Bob's end.

Both keys will be equal. Now Alice and Bob has a shared secret (alice_secret=bob_secret) which they can use to ecnrypt/decrypt messages.

Note that only public keys are exchanged here and a Man-In-The-Middle cannot get hold of either Alice's or Bob's private key.

The shared secret should be ideally converted to a proper symmetric key suitable for algorithms like AES by using a Key Derivation Function. Refer KDF

Pseudo-code

-Bob encrypts using bob_secret and AES:

  var crypto = require('crypto'),
  algo = 'aes-256-ctr',
  var cipher = crypto.createCipher(algo,bob_secret)
  var encrypted = cipher.update("foo-bar",'utf8','hex')
  encrypted += cipher.final('hex');

-Alice decrypts:

 var decipher = crypto.createDecipher(algo,alice_secret)
 var decrypted = decipher.update(encrypted,'hex','utf8')
 decrypted += decipher.final('utf8');