incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Encryption Library for data transfer between clients and CouchDB : a requirement in healthcare app.
Date Mon, 20 Dec 2010 18:43:01 GMT

We are about to release our first version of an EHR (Electronic Healthcare Record) build on
CouchDB. Now is time for us to deal in more details with data security issues in order to
protect patient data, particularly with data encryption on the net and signed documents. We
think about two ways and are willing to combine both when appropriate:
- using https (of course);
- using encryption and documents signing with PGP public/private keys;
- both may be used for health data.

We have read about similar questions on couchdb-user-archive (e.g. "Proposal For Storing Signatures
In JSON" including the article and cononical-json from Chris in the Couchdb Wiki, or the post
"Building Erlang app around CouchDB" which stated on Apr 21, 2009 "Common features such as
authentication, authorization, caching, compression, partitioning, proxying, tunneling, encryption
or URI rewriting are possible by placing standard applications such as Apache httpd or nginx
in front of your server.") but most posts are 1+ year old. Did I miss a current roadmap of
CouchDb on this topic?

In our case we need encryption on the client part and the server. We have all the javascript
code to build a library using PGP. Also, keys generation on the browser client appears fast
enough for 1024-bits keys (<5 secs) and subsequent encryption of docs takes only a few
millisecs. Our current idea is exposed thereafter. We would welcome CouchDB Guru's advices
and comments.

The principle we intend to implement is that both communication parties (local and remote)
generate their own private/public session keys and send their public key to the other party.
Then, during the session any data can be transfered encrypted and automatically decoded by
the receiver. We are writing a javascript library for a sort of encryption tunnel for communicating
between clients and CouchDB. We instanciate a Security object (which privately generates and
wraps the local private key for the session) and then exposes the following functions :
  - setRemotePublicKey(remotePublicKey) : to be called at most one time.
  - getPublicKey() : returns the local public key.
  - encode(content) : returns the PGP message of a content string encoded with the remotePublicKey.
  - decode(pgpMsg) : returns the decoded string of a PGP message which was encoded with the
local public key (getPublicKey()).
  - signDoc(couchDocument) : to add a digital signature to a document (the signature is only
valid for the session, so more to design here).

The workflow is the following. Given S a remote instance of Security on the CouchDB Server
and C the local instance of Security on the web Client. The lifetime C is the session, maybe
same for S. Only public keys travel the net and then encrypted data. The steps are as follows:

 1.  local  : C = new Security();
 2.  local  : send cPubKey = C.getPublicKey()
 3a. remote : receive cPubKey and execute S = new Security(cPubKey);
 3b. remote : now the remote is able to receive data encrypted by C.encode(content)
 3c. remote : decode encrypted data by local with S.decode(data)
 4.  remote : send sPubKey = S.getPublicKey()
 5.  local  : receive sPubKey and execute C.setRemotePublicKey(sPubKey);
 5b. local  : now local client can receive data encoded by remote party with S.encode(content)
 5c. local  : decode remote data with C.decode(data)

Alternate workflow : both local and remote instanciate simultaneously their new Security()
and send their getPublicKey(), when received, both execute the setRemotePublicKey() appropriately.
The normal sequence seems to be more natural since it allows the web client to generate its
local public key and send it to the remote server which create its Security and returns its
own public key as a result. Then, both parties know how to communicate. One problem could
arise if other async requests are pending: will they be encrypted or not? One way to answer
is to admit that both crypted and unencrypted data can be exchanged and will be recognized
on either the header of the response, or the '-----BEGIN PGP MESSAGE-----'.

Even better : integrating the security on the session creation when a client request CouchDB.
The CouchDB's gurus could explain if CouchDB could generate its Security instance on login
or session initialization (config.httpd_global_handlers? config.couch_httpd_auth?) and add
it to the session object (e.g. = {pubkey:'...', ...}). Could we get this
security feature as a standard or an optional plugin in CouchDB? We are ready to share our
security library and help the feature work. And it would be fine that the public key of the
client browser be sent with encrypted login data (which means that CouchDB send its public
key before client login).

Before going too far in developing such a security library, we would like to know if there
are alternate ways to deal with security and data encryption (+document signing) between the
web client and CouchDB. We are aware that in order to make this library transparent to users
and devs we should hook our library inside CouchDB in order that the data received from the
client is decoded appropriately (at some 'beforeProcess' event in CouchDB) and encoded before
sending data to the client (afterProcess event or beforeSending). Minor update of the CouchDB
Ajax code will make the encoding/decoding fully transparent on client's side.

More has to be designed for using certificates to be used independantly of the session duration.
But the principles will be the same, just the way we generate or acquired a valid certificate
(i.e. the public/private keys) will have to change.

Any comment welcome!

View raw message