简体   繁体   中英

Generate shared secret key from Curve25519 (or X25519) asymmetric key pairs in node.js using crypto module

I am trying to create a shared secret key between Curve25519 (or X25519) asymmetric key pairs using key exchange algorithms just like Diffie Hellman key exchange . Diffie Hellman key exchange can be be done in node.js using crypto module in the following code :

const crypto = require('crypto');

// Generate Alice's keys...
const alice = crypto.createDiffieHellman(2048);
const aliceKey = alice.generateKeys(); // Returns public key

// Generate Bob's keys...
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys(); // Returns public key

// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// Should be equal
console.log(aliceSecret === bobSecret)

X25519 asymmetric keys can be generated using the following code :

const crypto = require('crypto');
const { publicKey, privateKey } = crypto.generateKeyPairSync('x25519', {
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
  }
});

The keys are generated without any issue but I don't know how to generate a shared secret key. I tried converting X25519 keys to Diffie Hellman keys using the folowing code:

...
const dhKey= crypto.createDiffieHellman(2048);
// privateKey => Generated in the above code
dhKey.setPrivateKey(privateKey)
// publicKey => Generated in the above code
dhKey.setPublicKey(publicKey)
...

When using the above code when two dhKey are generated and key exchange is performed, it is giving the following error:

Error: Supplied key is too large

Is there any way the shared secret can be generated? Thanks in advance.

The documentation for this sub API is unfortunately a little thin. I cobbled together an example but without better documentation I'm not sure it's useful.

const crypto = require('crypto');

const aliceKeyPair = crypto.generateKeyPairSync('x25519');

const alicePubExport = aliceKeyPair.publicKey.export(
    {type: 'spki', format: 'pem'}
    );

const bobKeyPair = crypto.generateKeyPairSync('x25519');

const bobPubExport = bobKeyPair.publicKey.export(
    {type: 'spki', format: 'pem'}
    );

const bobKeyAgree = crypto.diffieHellman({
    publicKey : crypto.createPublicKey(alicePubExport),
    privateKey: bobKeyPair.privateKey
});

const aliceKeyAgree = crypto.diffieHellman({
    publicKey : crypto.createPublicKey(bobPubExport),
    privateKey: aliceKeyPair.privateKey
});

console.log(bobKeyAgree.toString('hex'));
console.log(aliceKeyAgree.toString('hex'));

This is missing authentication and therefore is not secure without adding that piece.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM