1

I'm making a service that will store personal data written about a given user, that should be viewable only by the author and the target. I would like to perform the encryption client-side and store only the resulting garbage on the server.

The internet tells me to use , this will work well for a single users's data.

Problem

For my service, other users are able to enter data that should be viewable only by them and the target user - how might this be accomplished with client side encryption?

Is it possible to do this purely client side?

Update

After considering this, I doubt it can be done purely client side. I have come up with the following possible method:

All traffic uses SSL connection

  • Generate a RSA keys, encrypt the private key with AES (using a salted passphrase)
    • Salt generated in-browser
  • Store the passphrase salt, public key, encrypted private key on the server
  • All user data encrypted with their public key, decrypted by having them first decrypt their private key in-browser by entering their passphrase, then using the RSA private key to decrypt the data

  • If the user wishes to share data with another, encrypt said data with the other user's public key

Is my suggested method secure?

Example of what would be stored on server:

+----------+---------------------+---------------+
|Public Key|Encrypted Private Key|Passphrase Salt|
+----------+---------------------+---------------+
Cœur
  • 37,241
  • 25
  • 195
  • 267
Michael Robinson
  • 29,278
  • 12
  • 104
  • 130
  • 1
    The problem is that if the client side JavaScript originates at the server then the client cannot fully trust the server, and if it can trust the server, then you normally don't need to encrypt anyway. JavaScript browser encryption is more or less useless without SSL/TLS, always keep that in mind. – Maarten Bodewes Jul 21 '13 at 14:45
  • @owlstead The idea is to prevent server-side leakage of the unencrypted data. Of course, there's always a risk of the server delivering the web page that has a backdoor (or uses no encryption at all), but this risk can be analysed on the client side (at least in theory :), but still client-side encryption adds trust and security. – Eugene Mayevski 'Callback Jul 21 '13 at 15:28
  • @EugeneMayevski'EldoSCorp As for making the data unreadable for somebody that somehow retrieves the database this scheme is OK. It is not OK with a lot of additional safeguards from anybody with access to the application server. This includes both attackers and the maintainers of the server. Finally, if the public key cannot be trusted then this scheme is not safe against man-in-the-middle attacks, at least not without TLS. Specific enough for you? – Maarten Bodewes Jul 21 '13 at 20:34
  • @owlstead I should have mentioned, all communication with the server will be via https – Michael Robinson Jul 21 '13 at 21:21
  • @MichaelRobinson OK, except for the comments I made before, this seems to be a sound scheme. Note that RSA encryption is pretty slow in JavaScript. Normally you would encrypt a random AES data key instead of using the private key directly. Problem is that you need a random AES key for that. To do this, it's probably best to mix up some entropy gathered at the client with random bytes from the server as JavaScript in the browser - by default - does not have a random data generator either. – Maarten Bodewes Jul 21 '13 at 23:04
  • Note that the absence of a good RNG plays hell with key generation and RSA encryption such as PKCS#1 v1.5 padding too. – Maarten Bodewes Jul 21 '13 at 23:25
  • @owlstead yes this does concern me, does requiring one to use a browser that implements `window.crypto.getRandomValues` sufficiently cover this? – Michael Robinson Jul 22 '13 at 00:00
  • @owlstead http://www-cs-students.stanford.edu/~tjw/jsbn/ will use it if available. I plan on detecting support and plainly refusing to continue if it isn't there. – Michael Robinson Jul 22 '13 at 05:32
  • @owlstead what you describe fits into overall insecurity of client-side JavaScript approach to encryption. You said nothing new here. – Eugene Mayevski 'Callback Jul 22 '13 at 05:59

1 Answers1

3

It would be much easier for you to deal with OpenPGP. OpenPGP uses public-key cryptography (RSA or Elgamal are used for encryption), so the scheme would be similar to what you describe but without the hassle of reinventing the wheel.

OpenPGP implementations exist for different languages including JavaScript (although using Javascript way is bad due to various security weaknesses that can lead to information disclosure). Yet your RSA scheme implemented in JavaScript would be equally vulnerable due to the same conceptual weaknesses.

One of benefits of OpenPGP is that users are either already acquainted with OpenPGP or can find plenty of information about it (which adds trust to your solution), and can already have their own keys. Also users can use any OpenPGP tool to generate keys and to open encrypted data.

Community
  • 1
  • 1
Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121