Elliptic Curve Diffie-Hellman and AES Example in Node.JS
Recently I learned how to generate shared secrets using ECDH in Node.JS, but I still had to know how to use this shared secret. Here is one application for it. Use the ECDH to generate a shared secret and then use that shared secret to cipher/decipher messages between both parties, in this case Joe and Zoe. Here is the code:
console.log("\n- ---[ Elliptic Curve Diffie-Hellman and AES Example ]--- -"); console.log("\n"); var crypto = require('crypto'); var assert = require('assert'); var CURVE_ALGORTHM = 'wap-wsg-idm-ecid-wtls11'; console.log("Elliptic Curve Algorithm: " + CURVE_ALGORTHM); console.log("\n"); // Generate Zoe's keys... var zoe = crypto.createECDH(CURVE_ALGORTHM); var zoeKey = zoe.generateKeys(); // Generating Joe's keys... var joe = crypto.createECDH(CURVE_ALGORTHM); var joeKey = joe.generateKeys(); // Exchange and generate secret... var zoeSecret = zoe.computeSecret(joeKey); var joeSecret = joe.computeSecret(zoeKey); assert.strictEqual(zoeSecret.toString('hex'), joeSecret.toString('hex')); console.log("Zoe's Public Key: " + zoe.getPublicKey('hex')); console.log("Zoe's Private Key: " + zoe.getPrivateKey('hex')); console.log("\n"); console.log("Joe's Public Key: " + joe.getPublicKey('hex')); console.log("Joe's Private Key: " + joe.getPrivateKey('hex')); console.log("\n"); zoeSecret = zoeSecret.toString('hex'); joeSecret = joeSecret.toString('hex'); console.log('Zoe secret: ' + zoeSecret); console.log('Joe secret: ' + joeSecret); console.log("\n"); // Using the generated shared Secrets to cipher/decipher messages between Zoe and Joe var AES256 = "aes256"; var zoeCipher = crypto.createCipher(AES256, zoeSecret); var zoeDecipher = crypto.createDecipher(AES256, zoeSecret); var joeCipher = crypto.createCipher(AES256, joeSecret); var joeDecipher = crypto.createDecipher(AES256, joeSecret); // Zoe ciphers a message for Joe var msg1 = "Hey Joe, I'm Zoe"; var eMsg1 = zoeCipher.update(msg1, 'utf8', 'hex'); eMsg1 += zoeCipher.final('hex'); console.log("Zoe says (clear): " + msg1); console.log("Zoe says (ciphered): " + eMsg1); console.log('\n'); // Joe deciphers Zoe's message var dMsg1 = joeDecipher.update(eMsg1, 'hex', 'utf8'); dMsg1 += joeDecipher.final('utf8'); console.log("Joe receives (ciphered): " + eMsg1); console.log("Joe receives (deciphered): " + dMsg1); console.log('\n'); // Joe ciphers a message for Zoe var msg2 = "Hey Zoe, how are you doing?"; var eMsg2 = joeCipher.update(msg2, 'utf8', 'hex'); eMsg2 += joeCipher.final('hex'); console.log("Joe says (clear): " + msg2); console.log("Joe says (ciphered): " + eMsg2); console.log('\n'); // Zoe deciphers Joe's message var dMsg2 = zoeDecipher.update(eMsg2, 'hex', 'utf8'); dMsg2 += zoeDecipher.final('utf8'); console.log("Zoe receives (ciphered): " + eMsg2); console.log("Zoe receives (deciphered): " + dMsg2);
Your console output should be similar to this:
E:\NodeJS>node ecdh-aes.js - ---[ Elliptic Curve Diffie-Hellman and AES Example ]--- - Elliptic Curve Algorithm: wap-wsg-idm-ecid-wtls11 Zoe's Public Key: 040070230a08f8fc62bf2f10430a5a2af6b7c56c931fc191d97e21c72ee32301da452a99347fc1bb13db4ee4f890ca4539025dfa153b2b0086aa4d5e16 Zoe's Private Key: 2b2d30cd93f9a6a20b2ec6c5ef15462e69001c6d56cd600457f47ade70 Joe's Public Key: 0400facfc4a4a2116444aa8f75b3afbf861aa85f4b451f999da94e6ba23b1a008ab778a77578a81cf54760320d0813bf0a855324014fe89501d0273249 Joe's Private Key: 3285f8be0f9c18b65de80aae0103c7d9811ef32decff46f9bfc0925d25 Zoe secret: 01b874f549145a04e6cd75fae7bf22c64a664960b5f0ecd9ddf061de767f Joe secret: 01b874f549145a04e6cd75fae7bf22c64a664960b5f0ecd9ddf061de767f Zoe says (clear): Hey Joe, I'm Zoe Zoe says (ciphered): 5bb662241f3a0b443e11b7162561a059e8a8a6f206569db8d12400a3e7bbb1ef Joe receives (ciphered): 5bb662241f3a0b443e11b7162561a059e8a8a6f206569db8d12400a3e7bbb1ef Joe receives (deciphered): Hey Joe, I'm Zoe Joe says (clear): Hey Zoe, how are you doing? Joe says (ciphered): c4b53b00b5e93170bb777b4036d377fea509b0c214df9459a5544e22aeb0b18e Zoe receives (ciphered): c4b53b00b5e93170bb777b4036d377fea509b0c214df9459a5544e22aeb0b18e Zoe receives (deciphered): Hey Zoe, how are you doing?
Sources
- https://nodejs.org/dist/latest-v8.x/docs/api/crypto.html#crypto_diffiehellman_generatekeys_encoding
- https://nodejs.org/dist/latest-v8.x/docs/api/crypto.html#crypto_diffiehellman_generatekeys_encoding
- https://security.stackexchange.com/questions/45963/diffie-hellman-key-exchange-in-plain-english
- http://andrea.corbellini.name/2015/05/30/elliptic-curve-cryptography-ecdh-and-ecdsa/
- https://cafedev.org/article/2016/11/secure-messages-in-nodejs-using-ecdh/
- https://www.entrust.com/wp-content/uploads/2014/07/Zero-to-ECDH-WEB-Dec15.pdf
- https://www.entrust.com/resource/zero-ecdh-elliptic-curve-diffie-hellman-30-minutes/