calvinmetcalf / crypto-pouch

plugin for encrypted pouchdb/couchdb databases
MIT License
243 stars 43 forks source link

Crypto-Pouch

CI NPM Version JS Standard Style

Plugin to encrypt a PouchDB database.

const PouchDB = require('pouchdb')
PouchDB.plugin(require('crypto-pouch'))

const db = new PouchDB('my_db')

// init; after this, docs will be transparently en/decrypted
db.crypto(password).then(() => {
  // db will now transparently encrypt writes and decrypt reads
  await db.put({ ... })
  // you can disable transparent en/decryption,
  // though encrypted docs remain encrypted
  db.removeCrypto()
})

Crypto-Pouch encrypts documents using TweetNaCl.js, an audited encryption library. It uses the xsalsa20-poly1305 algorithm.

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 only encrypts the contents of documents, not the _id or _rev, nor view keys and values. This means that _id values always remain unencrypted, and any keys or values emitted by views are stored unencrypted as well. If you need total encryption at rest, consider using the PouchDB plugin ComDB instead.

Usage

This plugin is hosted on npm. To install it in your project:

$ npm install crypto-pouch

Using Typescript? Install the type definitions:

$ npm install --save-dev @types/crypto-pouch

Usage

async db.crypto(password [, options])

Set up encryption on the database.

You may also pass an options object as the first parameter, like so:

db.crypto({ password, ignore: [...] }).then(() => {
  // database will now encrypt writes and decrypt reads
})

db.removeCrypto()

Disables encryption on the database and forgets your password.

Details

If you replicate to another database, Crypto-Pouch will decrypt documents before sending them to the target database. Documents received through replication will be encrypted before being saved to disk.

If you change the ID of a document, Crypto-Pouch 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.

Encrypted documents have only one custom property, payload, which contains the encrypted contents of the unencrypted document. So, { hello: 'world' } becomes { payload: '...' }. This payload value is produced by garbados-crypt; see that library for more details.

Development

First, get the source:

$ git clone git@github.com:calvinmetcalf/crypto-pouch.git
$ cd crypto-pouch
$ npm i

Use the test suite:

$ npm test

When contributing patches, be a good neighbor and include tests!

License

See LICENSE.