Giter Site home page Giter Site logo

ipfs-shipyard / js-human-crypto-keys Goto Github PK

View Code? Open in Web Editor NEW
30.0 16.0 6.0 1.58 MB

Generate and import human-friendly cryptographic keys using mnemonics, QR codes and other methods

License: MIT License

JavaScript 100.00%
crypto key human mnemonic qr-code paper-key

js-human-crypto-keys's Introduction

human-crypto-keys

NPM version Downloads Build Status Coverage Status Dependency status Dev Dependency status

Generate and import human-friendly cryptographic keys using mnemonics or seeds.

Installation

$ npm install human-crypto-keys

This library is written in modern JavaScript and is published in both CommonJS and ES module transpiled variants. If you target older browsers please make sure to transpile accordingly.

Usage

import { generateKeyPair, getKeyPairFromMnemonic, getKeyPairFromSeed } from 'human-crypto-keys';

const keyPair = await generateKeyPair('rsa');
// => Generates a key pair with rsa encryption and provides information for recovery.

const keyPairFromMnemonic = await getKeyPairFromMnemonic(keyPair.mnemonic, keyPair.algorithm);
// => Generates the same key pair based on the mnemonic.

const keyPairFromSeed = await getKeyPairFromSeed(keyPair.seed, keyPair.algorithm);
// => Generates the same key pair based on the seed.

⚠️ human-crypto-keys depends on cryptographic modules that can increase the bundle size of your projects significantly. You might want to break big bundles in smaller pieces with the help of dynamic imports.

API

generateKeyPair(algorithm, [options])

Generates a key pair based on the specified algorithm.

Returns an object with the following:

{
    algorithm,  // An object with the algorithm identifier and respective parameters that were used during generation.
    mnemonic,   // The mnemonic used to create a seed for generation.
    seed,       // The seed used for generation (Uint8Array).
    privateKey, // The generated private key composed in a specific format.
    publicKey,  // The generated public key composed in a specific format.
}

algorithm

Type: Object or String

The algorithm identifier and the respective parameters to generate a key pair. Please read the algorithm section for more information.

options

Type: Object

Options to be used while composing keys. Please read the options section for more information.

getKeyPairFromMnemonic(mnemonic, algorithm, [options])

Generates a key pair based on the specified mnemonic and algorithm.

Returns an object with the following:

{
    privateKey, // The generated private key composed in a specific format.
    publicKey,  // The generated public key composed in a specific format.
}

mnemonic

Type: String

The mnemonic provided as one of the recovery methods for a key pair.

algorithm

Type: Object or String

The algorithm identifier and the respective parameters to generate a key pair. Please read the algorithm section for more information.

options

Type: Object

Options to be used while composing keys. Please read the options section for more information.

getKeyPairFromSeed(seed, algorithm, [options])

Generates a key pair based on the specified seed and algorithm.

Returns an object with the following:

{
    privateKey, // The generated private key composed in a specific format.
    publicKey,  // The generated public key composed in a specific format.
}

seed

Type: Uint8Array

The seed provided as one of the recovery methods for a key pair.

algorithm

Type: Object or String

The algorithm identifier and the respective parameters to generate a key pair. Please read the algorithms section for more information.

options

Type: Object

Options to be used while composing keys. Please read the options section for more information.

Common Parameters

algorithm

Type: Object or String

The algorithm identifier and the respective parameters to generate a key pair.

It can be specified as an Object or a String. Using an Object will provide freedom to override default algorithm parameters in relation to its type. On the other hand, a String presents a useful and quick approach if the default parameters are suitable.

The default parameters are different for each algorithm type. Currently only 2 types are supported:

RSA

Default Parameters:

{
	modulusLength: 2048		    // Number
	publicExponent: 65537		// Number
	method: 'PRIMEINC'		    // String
}

You can override only the parameters that you need, all the other ones remain with default values.

⚠️ Please make sure that values follow the same type as default ones. Also, parameters that are not available as default are not supported.

Example Object:

const algorithm = { id: 'rsa', modulusLength: 4096 };

Example String:

const algorithm = 'rsa';

In the examples above we are using an alias for RSA encryption. Although this is possible, the full list of supported RSA key algorithms can be found in the RSA Keys Section of crypto-key-composer package.

Generation

The following steps detail how the generation of a RSA key pair is being done:

  1. Create a Pseudorandom Number Generator, prng for short, with HMAC-DRBG using a seed as its generation entropy. This seed is directly provided when using getKeyFromSeed or inferred from a mnemonic passed in getKeyFromMnemonic. If neither the seed nor the mnemonic are available they can both be generated, as done in generateKeyPair. The generation of a mnemonic and its derived seed are done with bip39, a well established method used in bitcoin wallets.
  2. Generate a key pair, using Node Forge RSA generation method, with all necessary algorithm parameters and the prng created previously.
  3. Compose both keys with the defined formats.
ED25519

This algorithm doesn't have any default parameters since it just relies on 32 bytes randomly generated.

Example Object:

const algorithm = { id: 'ed25519' };

Example String:

const algorithm = 'ed25519';
Generation

The following steps detail how the generation of a ED25519 key pair is being done:

  1. Generate a key pair, using Node Forge ED25519 generation method, with a 32 bytes seed. If the seed is bigger than the necessary size, only the first 32 bytes will be used. This seed is directly provided when using getKeyFromSeed or inferred from a mnemonic passed in getKeyFromMnemonic. If neither the seed nor the mnemonic are available they can both be generated, as done in generateKeyPair. The generation of a mnemonic and its derived seed are done with bip39, a well established method used in bitcoin wallets.
  2. Compose both keys with the defined formats.

options

Type: Object

The current options allow you to decide both private and public key formats, the private key encryption and the password to use to encrypt the key.

Available options:

privateKeyFormat

Type: String

Default: pkcs8-pem

The format in which the private key will be composed.

Keys can be composed in different formats and vary by algorithm. All formats available are described in the Formats Section of crypto-key-composer package.

publicKeyFormat

Type: String

Default: spki-pem

The format in which the public key will be composed.

Keys can be composed in different formats and vary by algorithm. All formats available are described in the Formats Section of crypto-key-composer package.

encryptionAlgorithm

Type: Object

The encryption algorithm that will be used to encrypt the private key.

For more information please read the Encryption Algorithms Section of crypto-key-composer package.

password

Type: String

The password to be used on the encryption of the private key.

Tests

$ npm test
$ npm test -- --watch # during development

License

Released under the MIT License.

js-human-crypto-keys's People

Contributors

paulobmarcos avatar satazor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-human-crypto-keys's Issues

Non-Deterministic and Incorrect Key-Pair from Mnemonic when `bip39` is pulled in as `3.1.0`

It seems that when this library pulls in bip39 as 3.1.0 we are getting incorrect key pairs from seed phrase to key pair generation.

There is some strange behavior going on here. The seed produced by bip39 remains the same each time we run it. But later on in the generate part of human-crypto-keys we see the results start to differ.

// src/testme.js

import { getKeyPairFromMnemonic } from "./index.js";
import * as bip39 from "bip39";

const mnemonic =
    "slender during cost problem tortoise extra deal walnut great oblige planet kid";

(async () => {
    const seedBuffer = await bip39.mnemonicToSeed(mnemonic);
    const seedBuffer2 = await bip39.mnemonicToSeed(mnemonic);
    console.log(
        "seed buffer to hex string from bip 39 mnemonic to seed are the same?",
        seedBuffer.toString("hex") === seedBuffer2.toString("hex")
    );

    const { privateKey } = await getKeyPairFromMnemonic(
        mnemonic,
        {
            id: "rsa",
            modulusLength: 4096,
        },
        { privateKeyFormat: "pkcs8-pem" }
    );
    const { privateKey: privateKey2 } = await getKeyPairFromMnemonic(
        mnemonic,
        {
            id: "rsa",
            modulusLength: 4096,
        },
        { privateKeyFormat: "pkcs8-pem" }
    );
    console.log(
        "private keys are the same after get key-pair from mnemonic?",
        privateKey === privateKey2
    );
})();

Results on bip39 3.0.2:

> node lib/testme.js
seed buffer to hex string from bip 39 mnemonic to seed are the same? true
private keys are the same after get keypair from mnemonic? true

Results on bip39 3.1.0:

> node lib/testme.js
seed buffer to hex string from bip 39 mnemonic to seed are the same? true
private keys are the same after get keypair from mnemonic? false

In the version 3.1.0, the bip39 package changed their dependencies substantially and added @noble/hashes. This new dependency seems to alter several global cryptos. I still don't yet understand why this would effect the outcome given that the result from bip39 remains the same -- but locking the version of bip39 to 3.0.2 does fix the issue on our end...

Web workers

The generation of keys can be computational heavy and the use of Web Workers could be beneficial since these operations could be done in a background thread separate from the main execution thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.

QR Code

Nowadays QR Codes are everywhere and a part of our life, so it would be useful to support a QR Code recovery mechanism.

Question - Cryptographic security of mnemonics

I'm not sure if this library is still maintained or not but have a question about how the mnemonics used to generate the wallets works. It looks like generateKeys is using a 12 word mnemonic to generate the random seed which equates to 128 bits of randomness (from looking at the bip39 library that is used). Is that enough randomness to securely generate an RSA key with a modulus of 4096 bits? @satazor @paulobmarcos

Expose word-list option

Currently, only the default word-list, an English based one, is being used.

We should provide and option to support other word-lists, as already supported by bip39:

bip39.setDefaultWordlist('italian')

bip39 currently supports the following:

  • chinese_simplified
  • chinese_traditional
  • english
  • french
  • italian
  • japanese
  • korean
  • spanish

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.