2017-12-06 08:49:16 +00:00
# js-libp2p-keychain
[](http://ipn.io)
[](http://ipfs.io/)
[](http://webchat.freenode.net/?channels=%23ipfs)
[](https://github.com/RichardLitt/standard-readme)
[](https://coveralls.io/github/libp2p/js-libp2p-keychain?branch=master)
[](https://travis-ci.org/libp2p/js-libp2p-keychain)
[](https://circleci.com/gh/libp2p/js-libp2p-keychain)
[](https://david-dm.org/libp2p/js-libp2p-keychain)
[](https://github.com/feross/standard)


2017-12-06 22:56:09 +13:00
> A secure key chain for libp2p in JavaScript
2018-06-25 15:06:17 +02:00
## Lead Maintainer
[Vasco Santos ](https://github.com/vasco-santos ).
2017-12-06 22:56:09 +13:00
## Features
- Manages the lifecycle of a key
- Keys are encrypted at rest
- Enforces the use of safe key names
- Uses encrypted PKCS 8 for key storage
- Uses PBKDF2 for a "stetched" key encryption key
- Enforces NIST SP 800-131A and NIST SP 800-132
- Uses PKCS 7: CMS (aka RFC 5652) to provide cryptographically protected messages
- Delays reporting errors to slow down brute force attacks
2017-12-06 08:49:16 +00:00
## Table of Contents
## Install
2017-12-06 13:40:12 +01:00
```sh
npm install --save libp2p-keychain
```
2017-12-06 23:13:02 +13:00
2017-12-06 22:56:09 +13:00
### Usage
2017-12-06 13:40:12 +01:00
```js
const Keychain = require('libp2p-keychain')
const FsStore = require('datastore-fs')
2017-12-06 23:13:02 +13:00
2017-12-06 13:40:12 +01:00
const datastore = new FsStore('./a-keystore')
const opts = {
passPhrase: 'some long easily remembered phrase'
}
const keychain = new Keychain(datastore, opts)
```
2017-12-06 22:56:09 +13:00
2017-12-06 08:49:16 +00:00
## API
2017-12-06 22:56:09 +13:00
Managing a key
- `createKey (name, type, size, callback)`
- `renameKey (oldName, newName, callback)`
- `removeKey (name, callback)`
2019-02-25 12:04:54 +01:00
- `exportKey (name, password, callback)` // Omit _password_ for `ed25199` or `secp256k1` keys
- `importKey (name, encKey, password, callback)` // Omit _password_ for `ed25199` or `secp256k1` keys
2017-12-06 22:56:09 +13:00
- `importPeer (name, peer, callback)`
A naming service for a key
- `listKeys (callback)`
- `findKeyById (id, callback)`
- `findKeyByName (name, callback)`
2019-02-25 12:04:54 +01:00
Cryptographically protected messages (Only supported with RSA keys)
2017-12-06 22:56:09 +13:00
2018-01-29 19:34:55 +13:00
- `cms.encrypt (name, plain, callback)`
- `cms.decrypt (cmsData, callback)`
2017-12-06 22:56:09 +13:00
### KeyInfo
The key management and naming service API all return a `KeyInfo` object. The `id` is a universally unique identifier for the key. The `name` is local to the key chain.
2017-12-06 13:40:12 +01:00
```js
2017-12-06 22:56:09 +13:00
{
name: 'rsa-key',
id: 'QmYWYSUZ4PV6MRFYpdtEDJBiGs4UrmE6g8wmAWSePekXVW'
}
```
The **key id** is the SHA-256 [multihash ](https://github.com/multiformats/multihash ) of its public key. The *public key* is a [protobuf encoding ](https://github.com/libp2p/js-libp2p-crypto/blob/master/src/keys/keys.proto.js ) containing a type and the [DER encoding ](https://en.wikipedia.org/wiki/X.690 ) of the PKCS [SubjectPublicKeyInfo ](https://www.ietf.org/rfc/rfc3279.txt ).
### Private key storage
2017-12-17 11:30:52 +13:00
A private key is stored as an encrypted PKCS 8 structure in the PEM format. It is protected by a key generated from the key chain's *passPhrase* using **PBKDF2** .
2017-12-06 22:56:09 +13:00
2017-12-21 02:43:54 +13:00
The default options for generating the derived encryption key are in the `dek` object. This, along with the passPhrase, is the input to a `PBKDF2` function.
2017-12-06 13:40:12 +01:00
```js
2017-12-06 22:56:09 +13:00
const defaultOptions = {
//See https://cryptosense.com/parameter-choice-for-pbkdf2/
dek: {
keyLength: 512 / 8,
2017-12-21 02:43:54 +13:00
iterationCount: 1000,
2017-12-17 11:30:52 +13:00
salt: 'at least 16 characters long',
hash: 'sha2-512'
2017-12-06 22:56:09 +13:00
}
}
```
2017-12-06 23:13:02 +13:00

2017-12-06 22:56:09 +13:00
### Physical storage
The actual physical storage of an encrypted key is left to implementations of [interface-datastore ](https://github.com/ipfs/interface-datastore/ ). A key benifit is that now the key chain can be used in browser with the [js-datastore-level ](https://github.com/ipfs/js-datastore-level ) implementation.
2018-01-29 19:34:55 +13:00
### Cryptographic Message Syntax (CMS)
CMS, aka [PKCS #7 ](https://en.wikipedia.org/wiki/PKCS ) and [RFC 5652 ](https://tools.ietf.org/html/rfc5652 ), describes an encapsulation syntax for data protection. It is used to digitally sign, digest, authenticate, or encrypt arbitrary message content. Basically, `cms.encrypt` creates a DER message that can be only be read by someone holding the private key.
2017-12-06 08:49:16 +00:00
## Contribute
Feel free to join in. All welcome. Open an [issue ](https://github.com/libp2p/js-libp2p-crypto/issues )!
This repository falls under the IPFS [Code of Conduct ](https://github.com/ipfs/community/blob/master/code-of-conduct.md ).
[](https://github.com/ipfs/community/blob/master/contributing.md)
## License
[MIT ](LICENSE )