‚̧Nihilist Postmodern Mistake
    Have ideas to improve npm?Join in the discussion! ¬Ľ

    eckles

    1.4.1¬†‚Äʬ†Public¬†‚Äʬ†Published

    Mirror of Eckles.js

    Official Repository: https://git.coolaj86.com/coolaj86/eckles.js

    Eckles.js

    A Root Project. Built for ACME.js and Greenlock.js

    | < 600 lines of code | 3kb gzipped | 10kb minified | 17kb with comments |

    ECDSA (elliptic curve) tools. Lightweight. Zero Dependencies. Universal compatibility.

    • Fast and Easy EC Key Generation
    • PEM-to-JWK
    • JWK-to-PEM
    • JWK thumbprint
    • SSH "pub" format
    • CLI
    • RSA

    Install

    For node.js:

    npm install --save eckles

    CLI:

    npm install -g eckles

    See Eckles CLI

    Generate EC (ECDSA/ECDH) Key

    Achieves the fastest possible key generation using node's native EC bindings to OpenSSL, then converts to JWK for ease-of-use.

    Eckles.generate({ format: 'jwk' }).then(function (keypair) {
      console.log(keypair.private);
      console.log(keypair.public);
    });

    options

    • format defaults to 'jwk'
      • 'sec1' (traditional)
      • 'pkcs8'
      • 'ssh'
    • encoding defaults to 'json'
      • 'pem' (type + DER.toString('base64'))
      • 'der'

    advanced options

    • namedCurve defaults to 'P-256'
      • P-384 is also supported
      • larger keys have not been implemented
        • A) because they're a senseless waste
        • B) they have similar, but slightly different formats

    PEM-to-JWK

    • SEC1/X9.62, PKCS#8, SPKI/PKIX
    • P-256 (prime256v1, secp256r1), P-384 (secp384r1)
    • SSH (RFC4716), (RFC 4716/SSH2)
    var Eckles = require('eckles');
    var pem = require('fs')
      .readFileSync('./node_modles/eckles/fixtures/privkey-ec-p256.sec1.pem', 'ascii');
     
    Eckles.import({ pem: pem }).then(function (jwk) {
      console.log(jwk);
    });
    {
      "kty": "EC",
      "crv": "P-256",
      "d": "iYydo27aNGO9DBUWeGEPD8oNi1LZDqfxPmQlieLBjVQ",
      "x": "IT1SWLxsacPiE5Z16jkopAn8_-85rMjgyCokrnjDft4",
      "y": "mP2JwOAOdMmXuwpxbKng3KZz27mz-nKWIlXJ3rzSGMo"
    }

    JWK-to-PEM

    • SEC1/X9.62, PKCS#8, SPKI/PKIX
    • P-256 (prime256v1, secp256r1), P-384 (secp384r1)
    • SSH (RFC4716), (RFC 4716/SSH2)
    var Eckles = require('eckles');
    var jwk = require('eckles/fixtures/privkey-ec-p256.jwk.json');
     
    Eckles.export({ jwk: jwk }).then(function (pem) {
      // PEM in SEC1 (x9.62) format
      console.log(pem);
    });
    -----BEGIN EC PRIVATE KEY-----
    MHcCAQEEIImMnaNu2jRjvQwVFnhhDw/KDYtS2Q6n8T5kJYniwY1UoAoGCCqGSM49
    AwEHoUQDQgAEIT1SWLxsacPiE5Z16jkopAn8/+85rMjgyCokrnjDft6Y/YnA4A50
    yZe7CnFsqeDcpnPbubP6cpYiVcnevNIYyg==
    -----END EC PRIVATE KEY-----
    

    Advanced Options

    format: 'pkcs8':

    The default output format is sec1/x9.62 (EC-specific format) is used for private keys. Use format: 'pkcs8' to output in PKCS#8 format instead.

    Eckles.export({ jwk: jwk, format: 'pkcs8' }).then(function (pem) {
      // PEM in PKCS#8 format
      console.log(pem);
    });
    -----BEGIN PRIVATE KEY-----
    MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiYydo27aNGO9DBUW
    eGEPD8oNi1LZDqfxPmQlieLBjVShRANCAAQhPVJYvGxpw+ITlnXqOSikCfz/7zms
    yODIKiSueMN+3pj9icDgDnTJl7sKcWyp4Nymc9u5s/pyliJVyd680hjK
    -----END PRIVATE KEY-----
    

    format: 'ssh':

    Although SSH uses SEC1 for private keys, it uses ts own special non-ASN1 format (affectionately known as rfc4716) for public keys. I got curious and then decided to add this format as well.

    To get the same format as you would get with ssh-keygen, pass ssh as the format option:

    Eckles.export({ jwk: jwk, format: 'ssh' }).then(function (pub) {
      // Special SSH2 Public Key format (RFC 4716)
      console.log(pub);
    });
    ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCE9Uli8bGnD4hOWdeo5KKQJ/P/vOazI4MgqJK54w37emP2JwOAOdMmXuwpxbKng3KZz27mz+nKWIlXJ3rzSGMo= P-256@localhost
    

    public: 'true':

    If a private key is used as input, a private key will be output.

    If you'd like to output a public key instead you can pass public: true or format: 'spki'.

    Eckles.export({ jwk: jwk, public: true }).then(function (pem) {
      // PEM in SPKI/PKIX format
      console.log(pem);
    });
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIT1SWLxsacPiE5Z16jkopAn8/+85
    rMjgyCokrnjDft6Y/YnA4A50yZe7CnFsqeDcpnPbubP6cpYiVcnevNIYyg==
    -----END PUBLIC KEY-----
    

    JWK Thumbprint

    Eckles.thumbprint({ jwk: jwk }).then(function (thumbprint) {
      console.log(thumbprint);
    });

    Testing

    All cases are tested in test.sh.

    You can compare these keys to the ones that you get from OpenSSL, ssh-keygen, and WebCrypto:

    # Generate EC P-256 Keypair 
    openssl ecparam -genkey -name prime256v1 -noout -out ./privkey-ec-p256.sec1.pem
     
    # Export Public-only EC Key (as SPKI) 
    openssl ec -in ./privkey-ec-p256.sec1.pem -pubout -out ./pub-ec-p256.spki.pem
     
    # Convert SEC1 (traditional) EC Keypair to PKCS8 format 
    openssl pkcs8 -topk8 -nocrypt -in ./privkey-ec-p256.sec1.pem -out ./privkey-ec-p256.pkcs8.pem
     
    # Convert EC public key to SSH format 
    ssh-keygen -f ./pub-ec-p256.spki.pem -i -mPKCS8 > ./pub-ec-p256.ssh.pub

    Goals of this project

    • Zero Dependencies
    • Focused support for P-256 and P-384, which are already universally supported.
    • Convert both ways
    • Browser support as well (TODO)
    • OpenSSL, ssh-keygen, and WebCrypto compatibility

    Legal

    Eckles.js | MPL-2.0 | Terms of Use | Privacy Policy

    Install

    npm i eckles

    DownloadsWeekly Downloads

    33,187

    Version

    1.4.1

    License

    MPL-2.0

    Unpacked Size

    28.6 kB

    Total Files

    22

    Last publish

    Collaborators

    • avatar