1

I'm writing a web app for Personal Information Management that runs in the Cloud. For that I'm considering client-side encryption using AES256 with window.crypto and SJCL as fall-back for older browsers. The encryption would then be based on the user's login password. In addition, I'm also thinking of doing the password hashing on the client side.

Is that actually increasing user privacy? Or am I missing anything? I know the standard way is to just store data "plain text" and do server side hashing.

EDIT To add a clearer scope, the intention is: in case the database gets stolen, the user data should be difficult to read. (At least it won't be plain data in that case.) At the same time, when user foo@gmail.com's uses 123456 for his mail account and for his WebApp PIM account, an attacker still has to reverse the password hash in order to access foo's Gmail.com.

In particular imagine the following scenario: an attacker can get the database and checks user foo@gmail.com's database records. He gets the hash, and some encrypted user data. With the hash he can login to WebApp PIM's API. However he can not read the user's data.

With the leaked hash, the attacker could easily compromise the data through the API, but that doesn't matter so much for this scenario. The primary goal is to increase privacy of the user data in case of a database leak.

(In addition I would like to allow the user to at least slightly distrust the WebApp hoster reading private data. I'm sure this solution doesn't get close to that, but at least it could be a first step.)

Regarding performance: the Web Crypto API can do PBKDF2 which seems fine to me for hashing. (Github Example) SJCL might be too slow as fallback, so it might make sense to transpile C++ to (asm.)js.

Philip
  • 199
  • 1
  • 7

1 Answers1

2

Please see this and this questions and all of the answers about client side hashing/encyption.

To sum it up, browser JavaScript is too slow for password hashing function like bcypt or scrypt which you will want to use to derive a key for AES from user password. You will need to reduce number of iterations and/or other hash parameters and thus reduce overall security of the implementation. If you want client side hashing/encyption, you will need to create browser extensions much like popular online password managers do.

EDIT:

If you or user distrusts WebApp hoster reading private data how can you trust WebApp hoster to deliver trustworthy code? What is to stop WebApp hoster injecting JavaScript code that will leak information before encryption?

To elaborate more directly about problems with browser cryptography please see these links: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/

https://tonyarcieri.com/whats-wrong-with-webcrypto

For a more recent opinion:

https://www.cossacklabs.com/whats-wrong-with-web-crypto.html

Regarding user privacy, you will not store plain text. You can use SSL to transmit plaintext and store it encrypted using a key derived from user password. Store hashed password for authentification. Do all encryption and hashing server side. Either that or deliver native application/web browser extension which can be signed and verified. In that case you don't have to trust WebApp hoster, you will just use it for (encrypted) data storage.

Marko Vodopija
  • 1,062
  • 1
  • 8
  • 19
  • Hey! Thanks a lot for the links, the last one fortunately also takes a positive turn regarding an NaCl solution... – Philip Mar 07 '17 at 19:46