ecdh ecdsa prime256v1 secp256r1 secp256k1
npm install ecdh-cryptoElliptic Curve Keys
===================
This project defines a wrapper for Elliptic Curve (EC) private and public keys.
* Curves;
* Basic Construction
* Randomly generated keys
* Instantiating from encoded keys
* Instantiating with objects
* ECDHCrypto properties
* ECDHCrypto functions
* asPublicECDHCrypto()
* computeSecret(otherKey)
* createECDH()
* createSign(hash)
* createVerify(hash)
* doSign(hash) Not PEM format
* doVVerify(hash, data) Not PEM format
* toBuffer(format)
* toString(format)
* toJSON()
* MIT License
Curves
------
This wrapper supports onl the three main curves listed below:
| OpenSSL Curve Name | RFC-7518 (6.2.1.1) | ASN.1 OID |
| ------------------ | ----------------------- | ------------------- |
| prime256v1 | P-256 | 1.2.840.10045.3.1.7 |
| secp384k1 | P-256K _non standard_ | 1.3.132.0.10 |
| secp384r1 | P-384 | 1.3.132.0.34 |
| secp521r1 | P-521 | 1.3.132.0.35 |
Both the OpenSSL names and RFC-7518 (JWA/JWK) names can be used as parameters
to the methods in the ECDHCrypto class.
Please be aware that _NodeJS_ (and _OpenSSL_) support a large number of curves
(see openssl ecparam -list_curves for a full list), but for brevity this
implementation restricts to the three mentioned above.
> PLEASE NOTE: The P-256K curve name (crv parameter) used when serializing
> a key using the secp384k1 curve is not standard, and NOT interoperable
> with other systems.
>
> See the IANA
> registry for all known (and interoperable) curve names.
>
> The P-256K name used might change at _ANY_ time.
Basic construction
------------------
To use, start importing the main ECDHCrypto class:
``javascript`
const ECDHCrypto = require('ecdh-crypto');
#### Randomly generated keys
To create a random ECDHCrypto instance simply call the createECDHCrypto staticprime256v1
method, optionally specifying a curve name (defaults to ):
`javascript`
// Create a new (random) ECDHCrypto instance using the secp521r1 curve
var randomKey = ECDHCrypto.createECDHCrypto('P-256');
#### Instantiating from encoded keys
To import an existing private or public key, simply invoke the constructor
with a String or a Buffer and the format in which the key is encoded:
`javascript`
// Create a new ECDHCrypto instance from a base-64 spki string
var key = new ECDHCrypto('MFkwEw ... 3w06qg', 'spki');
For Buffers and _base64-encoded_ Strings the constructor supports both thepkcs8 (or rfc5208) and spki (or rfc5280) formats.
Additionally, the pem format is supported for _unencoded_ Strings andBuffers:
`javascript`
// Load up a PEM file and wrap it into a
var pem = fs.readFileSync('./key.pem');
var key = new ECDHCrypto(pem, 'pem');
#### Instantiating with objects
Instances of the ECDHCrypto class can also be created from very simple object.
For example JWKs can be used directly, and whereas in the example below the
crv, x and y values will be considered, kty and kid will be ignored.
`javascript`
/// Simply create from a JWK object
var key = new ECDHCrypto({
"kty":"EC",
"crv":"P-256",
"x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
"kid":"Public key used in JWS spec Appendix A.3 example"
})
The following values are recognized:
* curve or crv: the curve type for this key, identified either by
its _OpenSSL_ or its _RFC-7518 (JWA/JWK)_ name.
With regards to coordinates:
* d: the private _d_ coordinate for the elliptic curve point, either as a
Buffer, or a _base64-encoded_ String of the coordinate's big endianx
representation
* : the public _x_ coordinate for the elliptic curve point, either as aBuffer
, or a _base64-encoded_ String of the coordinate's big endiany
representation
* : the public _y_ coordinate for the elliptic curve point, either as aBuffer
, or a _base64-encoded_ String of the coordinate's big endian
representation
And also:
* publicKey: the _uncompressed_ and _prefixed_ (0x04) concatenation of
the _x_ and _y_ public coordinates' big endian representation, as described
in SEC-1 ECC section 2.3.3
* privateKey: the private _d_ coordinate for the elliptic curve point,
either as a Buffer, or a _base64-encoded_ String of the coordinate's big
endian representation
ECDHCrypto properties
----------------
The following _enumerable_ properties are available for instances of ECDHCrypto:
* curve: the EC key curve name in _OpenSSL_ format (e.g. prime256v1)isPrivateECDHCrypto
* : a _boolean_ indicating whther this instance representsx
a _private_ or _public_ EC key.
* : the public _x_ coordinate's big endian representation for theBuffer
elliptic curve point as a y
* : the public _y_ coordinate's big endian representation for theBuffer
elliptic curve point as a d
* : the private _d_ coordinate's big endian representation for theBuffer
elliptic curve point as a
Additionally the following properties are available, but not _enumerable_:
* jsonCurve: the EC key curve name in _RFC-7518_ format (e.g. P-256)publicCodePoint
* : the _uncompressed_ and _prefixed_ (0x04) concatenation of
the _x_ and _y_ public coordinates' big endian representation, as described
in SEC-1 ECC section 2.3.3.
ECDHCrypto functions
---------------
#### asPublicECDHCrypto()
Return this instance if this key is a _public_ key, or create a new ECDHCrypto
instance not including the _private_ components of the key.
#### computeSecret(otherKey)
A simple shortcut for createECDH().computeSecret(otherKey) as explained below.
#### createECDH()
Create a standard Node _ECDH_
object instance whose computeSecret(...)
function accepts also ECDHCrypto (as in, this class) instances.
#### createSign(hash)
Create a standard Node _Sign_
object whose sign(...)
function is automatically populated with this instance.
* hash: the hashing function to use for generating the signature, normally oneSHA256
of , SHA384 or SHA512.
`javascript`
// Create a signature of the message "the quick brown fox" with a random key
var message = "the quick brown fox";
var key = ECDHCrypto.createECDHCrypto('P-384');
var signature = key.createSign('SHA384')
.update(message)
.sign('base64');
#### createVerify(hash)
Create a standard Node _Verify_
object whose verify(...)
function is automatically populated with this instance.
* hash: the hashing function to use for generating the signature, normally oneSHA256
of , SHA384 or SHA512.
`javascript`
// Verify the signature calcuated above
key.createVerify('SHA384')
.update(message)
.verify(signature, 'base64');
Encode this EC key, optionally using the specified format (defaults to pem).
Formats supported are as follows:
* pem: return a Buffer containing the ascii represtation of thenew Buffer(key.toString('pem'), 'ascii')
OpenSSL PEM format
* equivalent to and provided forrfc5951
convenience only
* : (_private_ keys only) returns the encoding of this key aspkcs8
specified by RFC-5951
* or rfc5208: (_private_ keys only) returns the PKCS8 encodingspki
of this key as specified by RFC-5208
* or rfc5280: (_public_ keys only) returns the SPKI encoding
of this key as specified by RFC-5280
Encode this EC key, optionally using the specified format (defaults to pem).
Formats supported are as follows:
* pem: return the key in OpenSSL's PEM format
* rfc5951: (_private_ keys only) returns the encoding of this key as
specified by RFC-5951, wrapped with
a header and footer as outlined in section 4
* pkcs8 or rfc5208: (_private_ keys only) returns the PKCS8 encoding
of this key as specified by RFC-5208
encoded in _base64_
* spki or rfc5280: (_public_ keys only) returns the SPKI encoding
of this key as specified by RFC-5280
encoded in _base64_
Formats this ECDHCrypto as a JSON Web Key as specified by
RFC-7517.
Please note that his function will also be called by the JSON.stringify(...)
function.
`javascript
// Convert a PEM to a JWK in one easy step
var pem = -----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgzr+Twxehecu0VYoC
XUBL1Z4h3H28gPnJ5MP0AcOixAOhRANCAAS6pMWMMndZxOPSC9ui6sUUbmeK6dIi
k3ZwTmm0SE7G+tYon5C57aVek5qH4y4OipbSLfbsIQuOkt0G8Vu1KZ3u
-----END PRIVATE KEY-----;
var key = new ECDHCrypto(pem, 'pem');
var jwk = JSON.stringify(key, null, 2);
console.log(jwk);
// This will result in the following output:
// {
// "kty": "EC",
// "crv": "P-256",
// "x": "uqTFjDJ3WcTj0gvbourFFG5niunSIpN2cE5ptEhOxvo",
// "y": "1iifkLntpV6TmofjLg6KltIt9uwhC46S3QbxW7Upne4",
// "d": "zr-Twxehecu0VYoCXUBL1Z4h3H28gPnJ5MP0AcOixAM"
// }
``
###example``
1. create
const ECDHCrypto = require('ecdh-crypto')
this.randomKey = ECDHCrypto.createECDHCrypto()
var publickey = this.randomKey.asPublicECDHCrypto()
this.publicKey = JSON.stringify(publickey);
2. signature
data = 'SER123456789' + this.publicKey
var signvalue = this.randomKey.doSign(data)
3. verify signagure
var value = this.randomKey.doVerify(data, signvalue)