Skip to content
Key management and cryptographically protected messages
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Discourse posts Dependency Status js-standard-style

A secure key chain for libp2p in JavaScript

Lead Maintainer

Vasco Santos.


  • 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

Table of Contents


npm install --save libp2p-keychain


const Keychain = require('libp2p-keychain')
const FsStore = require('datastore-fs')

const datastore = new FsStore('./a-keystore')
const opts = {
  passPhrase: 'some long easily remembered phrase'
const keychain = new Keychain(datastore, opts)


Managing a key

  • async createKey (name, type, size)
  • async renameKey (oldName, newName)
  • async removeKey (name)
  • async exportKey (name, password)
  • async importKey (name, pem, password)
  • async importPeer (name, peer)

A naming service for a key

  • async listKeys ()
  • async findKeyById (id)
  • async findKeyByName (name)

Cryptographically protected messages

  • async cms.encrypt (name, plain)
  • async cms.decrypt (cmsData)


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.

  name: 'rsa-key',
  id: 'QmYWYSUZ4PV6MRFYpdtEDJBiGs4UrmE6g8wmAWSePekXVW'

The key id is the SHA-256 multihash of its public key. The public key is a protobuf encoding containing a type and the DER encoding of the PKCS SubjectPublicKeyInfo.

Private key storage

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.

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.

const defaultOptions = {
  dek: {
    keyLength: 512 / 8,
    iterationCount: 1000,
    salt: 'at least 16 characters long',
    hash: 'sha2-512'

key storage

Physical storage

The actual physical storage of an encrypted key is left to implementations of interface-datastore. A key benifit is that now the key chain can be used in browser with the js-datastore-level implementation.

Cryptographic Message Syntax (CMS)

CMS, aka PKCS #7 and RFC 5652, 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.


Feel free to join in. All welcome. Open an issue!

This repository falls under the IPFS Code of Conduct.



You can’t perform that action at this time.