You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Jay Zamboni <jz...@vretina.com> on 2011/11/09 18:58:09 UTC

Handling encryption keys in a disconnected environment

Hello fellow couchdb users



We are creating a couchapp that will reside on a wireless client.  There
will be one central server and multiple clients that are accessing and
syncing the same database.  We are using the couchdb session based
authentication for our login.



Some of the data we store on the client needs to be encrypted in case the
device is lost or stolen.  The server will encrypt the data before it is
sent to the client and the client can securely request the encryption key
from the server when needed.  This works fine when we have a network
connection, but we want the client application to be able to decrypt data
even when it cannot connect to the server.  This seems to force us to store
the decryption key on the client with the encrypted data.  Storing the key
locally seriously weakens our security so we would want to at least encrypt
the stored key with the users password(+salt).  The authentication in
couchdb does not store the password, it stores a password hash.  That’s a
good thing, but it means our users would have to enter their password for
every page that displays this encrypted data.  This would happen enough
that disconnected usage would become very frustrating.  We could pass the
password around from page to page, but that weakens our security even more.



The current idea we are discussing is:



User logs in

            Decrypt stored key with user entered password

            Create session (Get session id for couch session.  Not sure how
to do this yet.)

            Encrypt key using session id and store in couch



As the user goes from page to page we would use the session id to load the
encryption key.  When the user logs out or the session times out, the
session id should not exist anywhere.



The application is planned as a free download for users interested in the
product, so we are trying to avoid options that will be obstacles to the
user being able to try it.  That being said, the security of this data is
very important, so we need to come up with a strong solution.  If anyone
has ideas or experience with this kind of thing, I would love to have more
input.



Thanks



Jay

Re: Handling encryption keys in a disconnected environment

Posted by Jay Zamboni <jz...@vretina.com>.
Thanks Jim



I need to research the use of certificates more.  We can have the concept
of an admin user that gets each client device loaded with a certificate
prior to it’s usage.  Clearly we want this to be as hassle free as
possible, but our clients would share our security concerns so we can hope
they will forgive some of the installation complexities.



<<You should NEVER transmit a private key across the internet. Exposing any
kind of private key

<<material into the web client is just not a good idea.



We considered passing the private key, but it would be passed encrypted
with the users password and via SSL.  We could use a public/private key
solution as described here:



http://www.mail-archive.com/user@couchdb.apache.org/msg12063.html



This makes things more secure as far as writing data, but doesn’t really
help with the security of reading the data.



>>I'd also advise against using any JS-crypto solution, as the algorithms
can be compromised via

>>a XSS scripting attack unless your client can sandbox and secure the
algorithms somehow.



I have considered using a JS-crypto but isolating it to the show and update
functions so that it is running in couch instead of the browser.  I have
also considered doing it in erlang as described here:



http://web.archiveorange.com/archive/v/oW6DzmgYHcRrVUfqBqyf



However, I don’t know erlang and worry about the learning curve.


Thanks for the link and the information on keygen.  I’ll see if I can come
up with something better with this information.  I'll be looking at Jens
idea of a PhoneGap app using some keychain API as well.




Jay

Re: Handling encryption keys in a disconnected environment

Posted by Jim Klo <ji...@sri.com>.
While not specifically CouchDB related, currently there just is not a good way to deal with this natively in the browser, unless you're using x509 certificates that can be stored in the local device keystore. You should NEVER transmit a private key across the internet. Exposing any kind of private key material into the web client is just not a good idea. I'd suggest using the <keygen> tag to generate a client certificate which the public portion could be countersigned by the remote certificate.  If there is a way for the local client app to verify the counter-signature. You could then operate only with this client cert when disconnected.  There's an example of this sort of workflow here for generating and installing a ert like this here: http://goo.gl/PrxTr 

If you can generate the keys locally and distribute the public key to the remote service... which countersigns and and sends the certificate back to be installed on the client.  You should theoretically be able to store everything encrypted locally with the same private key which never left the client.  The trick is going to be using the private key to decrypt the local data when disconnected, AFAIK this is typically handled by the browser not by the web app.

I'd also advise against using any JS-crypto solution, as the algorithms can be compromised via a XSS scripting attack unless your client can sandbox and secure the algorithms somehow.

There is actually a W3C Web Cryptography working group that is in the process of being chartered this month to work out this very issue: http://www.w3.org/wiki/IdentityCharter

Jim Klo
Senior Software Engineer
Center for Software Engineering
SRI International




On Nov 9, 2011, at 1:13 PM, Jens Alfke wrote:

> 
> On Nov 9, 2011, at 9:58 AM, Jay Zamboni wrote:
> 
> we want the client application to be able to decrypt data
> even when it cannot connect to the server.  This seems to force us to store
> the decryption key on the client with the encrypted data.  Storing the key
> locally seriously weakens our security so we would want to at least encrypt
> the stored key with the users password(+salt).
> 
> Is this a pure web-app or will it have native components? iOS has APIs for storing secrets like keys in a secure encrypted “keychain”. I’m sure Android has a similar feature. (Even if you’re going to use a wrapper like PhoneGap to package your app for mobile devices, then that’s likely to have JavaScript bindings for those APIs.)
> 
>           Encrypt key using session id and store in couch
> As the user goes from page to page we would use the session id to load the
> encryption key.  When the user logs out or the session times out, the
> session id should not exist anywhere.
> 
> I don’t know the implementation details of how CouchDB tracks sessions, but if it stores the currently active session IDs on disk, then this won’t be secure, as an attacker can look at the server’s files and locate both the session key and the server key that was encrypted with it.
> 
> —Jens


Re: Handling encryption keys in a disconnected environment

Posted by Jay Zamboni <jz...@vretina.com>.
Thanks for the input Jens



<< Is this a pure web-app or will it have native components?



The ideal solution was intended to be a pure web app.  We have considered a
native/html solution like PhoneGap for other reasons.  I suppose this adds
more weight in that direction.



<<I don’t know the implementation details of how CouchDB tracks sessions,
but if it stores the currently active session IDs on disk, then this won’t
be secure,



The session id would not necessary have to be the couch session id.  If we
generate an id on login and post it as we go from page to page it would not
be stored on disk, however it would be in the browser memory, so the
session concept is a flawed solution.



Thanks again



Jay

On Wed, Nov 9, 2011 at 2:13 PM, Jens Alfke <je...@couchbase.com> wrote:

>
> On Nov 9, 2011, at 9:58 AM, Jay Zamboni wrote:
>
> we want the client application to be able to decrypt data
> even when it cannot connect to the server.  This seems to force us to store
> the decryption key on the client with the encrypted data.  Storing the key
> locally seriously weakens our security so we would want to at least encrypt
> the stored key with the users password(+salt).
>
> Is this a pure web-app or will it have native components? iOS has APIs for
> storing secrets like keys in a secure encrypted “keychain”. I’m sure
> Android has a similar feature. (Even if you’re going to use a wrapper like
> PhoneGap to package your app for mobile devices, then that’s likely to have
> JavaScript bindings for those APIs.)
>
>           Encrypt key using session id and store in couch
> As the user goes from page to page we would use the session id to load the
> encryption key.  When the user logs out or the session times out, the
> session id should not exist anywhere.
>
> I don’t know the implementation details of how CouchDB tracks sessions,
> but if it stores the currently active session IDs on disk, then this won’t
> be secure, as an attacker can look at the server’s files and locate both
> the session key and the server key that was encrypted with it.
>
> —Jens
>

Re: Handling encryption keys in a disconnected environment

Posted by Jens Alfke <je...@couchbase.com>.
On Nov 9, 2011, at 9:58 AM, Jay Zamboni wrote:

we want the client application to be able to decrypt data
even when it cannot connect to the server.  This seems to force us to store
the decryption key on the client with the encrypted data.  Storing the key
locally seriously weakens our security so we would want to at least encrypt
the stored key with the users password(+salt).

Is this a pure web-app or will it have native components? iOS has APIs for storing secrets like keys in a secure encrypted “keychain”. I’m sure Android has a similar feature. (Even if you’re going to use a wrapper like PhoneGap to package your app for mobile devices, then that’s likely to have JavaScript bindings for those APIs.)

           Encrypt key using session id and store in couch
As the user goes from page to page we would use the session id to load the
encryption key.  When the user logs out or the session times out, the
session id should not exist anywhere.

I don’t know the implementation details of how CouchDB tracks sessions, but if it stores the currently active session IDs on disk, then this won’t be secure, as an attacker can look at the server’s files and locate both the session key and the server key that was encrypted with it.

—Jens