The ECDH class is a utility for creating Elliptic Curve Diffie-Hellman (ECDH)
key exchanges.
Instances of the ECDH class can be created using the
crypto.createECDH() function.
import assert from 'node:assert'; const { createECDH, } = await import('node:crypto'); // Generate Alice's keys... const alice = createECDH('secp521r1'); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createECDH('secp521r1'); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); // OK
const assert = require('node:assert'); const { createECDH, } = require('node:crypto'); // Generate Alice's keys... const alice = createECDH('secp521r1'); const aliceKey = alice.generateKeys(); // Generate Bob's keys... const bob = createECDH('secp521r1'); const bobKey = bob.generateKeys(); // Exchange and generate the secret... const aliceSecret = alice.computeSecret(bobKey); const bobSecret = bob.computeSecret(aliceKey); assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex')); // OK
ECDH.convertKey(key, curve, inputEncoding?, outputEncoding?, format?): Buffer | string
Converts the EC Diffie-Hellman public key specified by key and curve to the
format specified by format. The format argument specifies point encoding
and can be 'compressed', 'uncompressed' or 'hybrid'. The supplied key is
interpreted using the specified inputEncoding, and the returned key is encoded
using the specified outputEncoding.
Use crypto.getCurves() to obtain a list of available curve names.
On recent OpenSSL releases, openssl ecparam -list_curves will also display
the name and description of each available elliptic curve.
If format is not specified the point will be returned in 'uncompressed'
format.
If the inputEncoding is not provided, key is expected to be a Buffer,
TypedArray, or DataView.
Example (uncompressing a key):
const { createECDH, ECDH, } = await import('node:crypto'); const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); const compressedKey = ecdh.getPublicKey('hex', 'compressed'); const uncompressedKey = ECDH.convertKey(compressedKey, 'secp256k1', 'hex', 'hex', 'uncompressed'); // The converted key and the uncompressed public key should be the same console.log(uncompressedKey === ecdh.getPublicKey('hex'));
const { createECDH, ECDH, } = require('node:crypto'); const ecdh = createECDH('secp256k1'); ecdh.generateKeys(); const compressedKey = ecdh.getPublicKey('hex', 'compressed'); const uncompressedKey = ECDH.convertKey(compressedKey, 'secp256k1', 'hex', 'hex', 'uncompressed'); // The converted key and the uncompressed public key should be the same console.log(uncompressedKey === ecdh.getPublicKey('hex'));
ecdh.computeSecret(otherPublicKey, inputEncoding?, outputEncoding?): Buffer | string
Computes the shared secret using otherPublicKey as the other
party's public key and returns the computed shared secret. The supplied
key is interpreted using specified inputEncoding, and the returned secret
is encoded using the specified outputEncoding.
If the inputEncoding is not
provided, otherPublicKey is expected to be a Buffer, TypedArray, or
DataView.
If outputEncoding is given a string will be returned; otherwise a
Buffer is returned.
ecdh.computeSecret will throw an
ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY error when otherPublicKey
lies outside of the elliptic curve. Since otherPublicKey is
usually supplied from a remote user over an insecure network,
be sure to handle this exception accordingly.
ecdh.generateKeys(encoding?, format?): Buffer | string
Generates private and public EC Diffie-Hellman key values, and returns
the public key in the specified format and encoding. This key should be
transferred to the other party.
The format argument specifies point encoding and can be 'compressed' or
'uncompressed'. If format is not specified, the point will be returned in
'uncompressed' format.
If encoding is provided a string is returned; otherwise a Buffer
is returned.
ecdh.getPrivateKey(encoding?): Buffer | string
If encoding is specified, a string is returned; otherwise a Buffer is
returned.
ecdh.getPublicKey(encoding?, format?): Buffer | string
The format argument specifies point encoding and can be 'compressed' or
'uncompressed'. If format is not specified the point will be returned in
'uncompressed' format.
If encoding is specified, a string is returned; otherwise a Buffer is
returned.
ecdh.setPrivateKey(privateKey, encoding?): void
string | ArrayBuffer | Buffer | TypedArray | DataViewSets the EC Diffie-Hellman private key.
If encoding is provided, privateKey is expected
to be a string; otherwise privateKey is expected to be a Buffer,
TypedArray, or DataView.
If privateKey is not valid for the curve specified when the ECDH object was
created, an error is thrown. Upon setting the private key, the associated
public point (key) is also generated and set in the ECDH object.
ecdh.setPublicKey(publicKey, encoding?): void
string | ArrayBuffer | Buffer | TypedArray | DataViewSets the EC Diffie-Hellman public key.
If encoding is provided publicKey is expected to
be a string; otherwise a Buffer, TypedArray, or DataView is expected.
There is not normally a reason to call this method because ECDH
only requires a private key and the other party's public key to compute the
shared secret. Typically either ecdh.generateKeys() or
ecdh.setPrivateKey() will be called. The ecdh.setPrivateKey() method
attempts to generate the public point/key associated with the private key being
set.
Example (obtaining a shared secret):
const { createECDH, createHash, } = await import('node:crypto'); const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); // This is a shortcut way of specifying one of Alice's previous private // keys. It would be unwise to use such a predictable private key in a real // application. alice.setPrivateKey( createHash('sha256').update('alice', 'utf8').digest(), ); // Bob uses a newly generated cryptographically strong // pseudorandom key pair bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); // aliceSecret and bobSecret should be the same shared secret value console.log(aliceSecret === bobSecret);
const { createECDH, createHash, } = require('node:crypto'); const alice = createECDH('secp256k1'); const bob = createECDH('secp256k1'); // This is a shortcut way of specifying one of Alice's previous private // keys. It would be unwise to use such a predictable private key in a real // application. alice.setPrivateKey( createHash('sha256').update('alice', 'utf8').digest(), ); // Bob uses a newly generated cryptographically strong // pseudorandom key pair bob.generateKeys(); const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); // aliceSecret and bobSecret should be the same shared secret value console.log(aliceSecret === bobSecret);