encrypted pouchdb/couchdb database
Last updated 5 years ago by gr2m .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install @gr2m/crypto-pouch 
SYNC missed versions from official npm registry.


crypto pouch Build Status

Plugin to encrypt a PouchDB/CouchDB database.

var db = new PouchDB('my_db');

db.crypto(password, {exclude: ['_attachments']});
// all done, docs should be transparently encrypted/decrypted

// will no longer encrypt decrypt your data

It currently encrypts with the Chacha20-Poly1305 algorithm, but this may be changed to AES256-GCM when Node 0.12.0 drops.

Note: Attachments cannot be encrypted at this point. Use {ignore: '_attachments'} to leave attachments unencrypted. Also note that db.putAttachment / db.getAttachment are not supported. Use db.put and db.get({binary: true, attachment: true}) instead. (#18)


This plugin is hosted on npm. To use in Node.js:

npm install crypto-pouch

If you want to use it in the browser, download the browserified version from wzrd.in and then include it after pouchdb:

<script src="pouchdb.js"></script>
<script src="pouchdb.crypto-pouch.js"></script>


db.crypto(password [, options])

Set up encryption on the database.

If the second argument is an object:

  • options.ignore
    String or Array of Strings of properties that will not be encrypted.


Disables encryption on the database.


If you replicate to another database, it will decrypt before sending it to the external one. So make sure that one also has a password set as well if you want it encrypted too.

If you change the name of a document, it will throw an error when you try to decrypt it. If you manually move a document from one database to another, it will not decrypt correctly. If you need to decrypt it a file manually you will find a local doc named _local/crypto in the database. This doc has a field named salt which is a hex-encoded buffer. Run on your password with that as salt for 1000 iterations to generate a 32 byte (256 bit) key; that is the key for decoding documents.

Each document has 3 relevant fields: data, nonce, and tag. nonce is the initialization vector to give to chacha20 in addition to the key you generated. Pass the document _id as additional authenticated data and the tag as the auth tag and then decrypt the data. If it throws an error, then you either screwed up or somebody modified the data.


Derive key from password and salt

db.get('_local/crypto').then(function (doc) {
  return new Promise(function (resolve, reject) {
    crypto.pbkdf2(password, doc.salt, 1000, 256/8, function (err, key) {
      if (err) {
        return reject(err);
}).then(function (key) {
  // you have the key

Decrypt a document

var chacha = require('chacha');

db.get(id).then(function (doc) {
   var decipher = chacha.createDecipher(key, new Buffer(doc.nonce, 'hex'));
  decipher.setAAD(new Buffer(doc._id));
  decipher.setAuthTag(new Buffer(doc.tag, 'hex'));
  var out = decipher.update(new Buffer(doc.data, 'hex')).toString();
  // parse it AFTER calling final
  // you don't want to parse it if it has been manipulated
  out = JSON.parse(out);
  out._id = doc._id;
  out._rev = doc._rev;
  return out;

Current Tags

  • 2.0.1                                ...           latest (5 years ago)

2 Versions

  • 2.0.1                                ...           5 years ago
  • 2.0.0                                ...           5 years ago
Maintainers (1)
Today 0
This Week 2
This Month 2
Last Day 0
Last Week 0
Last Month 2
Dependencies (6)
Dev Dependencies (6)
Dependents (0)

Copyright 2014 - 2016 © taobao.org |