Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I savely store encrypted user data on my server, and serve it only to the right user?

Let's assume I must store user's sensitive data, which was optionally encrypted on the client side.

  • Encryption (optional) should be done with user's passphrase.
  • User login (optional) should be done with user's password.

Notes:
A plain-text password is not stored on the server or transferred over the network.

My options and their drawbacks:

1. No authentication, Client-side authorization:
The server gives the data to everyone, but only the original user have the means to decode.
Data can be used by anyone to try to crack the encryption - not the best way to secure it.

2. Server-side authentication, no authorization:
Server stores user's password to access the data, and only gives the data to the user that can provide the right password.
Users don't trust the network for transferring their data without encryption.

3. Authentication and authorization:
Server stores user's password to access the encrypted data, the encryption is done using the passphrase that is different from user's password.
Good security, but users don't want to remember two passwords.

4. Authentication vs. Authorization: Server stores user's password to access the encrypted data, the encryption is done using the same password.
Users are happy. Some security concerns.

I prefer the latest fourth option, but my concern is:
What if the server will get compromised, how can I be sure that encrypted password and encrypted data can't be used together to break the encryption? How can I make it harder to break the encryption?

Some thoughts:

  • Use different encryption algorithms for password and data.
  • Add fixed string to the end of the user's password before encryption.
  • Pad user's password to some length.

EDIT:

The system should be very similar to a backup system that should be secure from all sides: the server should not be able to read the data, only the original client should be able to access the data and man in the middle attacks should be prevented. So if someone hacks the server authentication or the client encryption, the data should not be revealed.

It should be web based, so the man in the middle attack should be prevented with HTTPS.

To prevent server hacks revealing the data, the data is encrypted in client-side.

To prevent client encryption tampering, the access to the data should be protected on the server side with some log in and password or a token (may be unique URL).

like image 506
m_vitaly Avatar asked Dec 21 '22 23:12

m_vitaly


1 Answers

@Vitaly, permit me to clarify some terms before I answer, as you seem to be using a different meaning for some than is commonly used.

Authentication - the process of proving who you are (more accurately, that you own the identity you are claiming).
Authorization - the mechanism used to restrict, control, and grant access.
Encryption - a mechanism for protecting data, even from someone who has access to it.

Now, allow me to rephrase your options, and then I'll suggest something else:

  1. No Authentication, No Authorization, Client-side encryption
  2. Server-side authentication, Server-side authorization, Server-side encryption
  3. Server-side authentication, Server-side authorization, Client-side encryption
  4. Server-side authentication, Server-side authorization, Client-side encryption using server credentials.

Now, I think it can be clearer where each one stands.
In general, you really want to follow the "best practice" (dont get me started on those) principle of "Defense in depth", i.e. dont use only encryption, or only access control, instead use both! But, as you pointed out, this can be in contrast (if the user is required to remember TWO passwords) to another principle, "Keep Security Simple".

Without trying to be TOO annoying, you didn't give much information in the way of your environment. For example, is this e.g. a Web application? If so, why is SSL/TLS not enough encryption for you? Or is this a question of users uploading personal data that you (and your system) should not see either (e.g. a backup-type service)? In which case client-side encryption would be necessary...

So, (finally) my proposed options, depending on your environment / requirements:

  1. If you can, rely on secure protocols (e.g. SSL/TLS) for encryption. Use server-side authentication + authorization, protocol encryption.
  2. If your system needs to further protect this data, e.g. credit cards (note that I am not currently a PCI:QSA ;) ), use the previous option, and in addition server-side encryption using a server-generated encryption key (NOT the password) (and of course protect that).
  3. If the data needs to be protected FROM your system, you will need to do client-side encryption IN ADDITION to server-side authentication+authorization (your option 3 as I restated it).
    However, you don't necessarily need to force the user to remember an additional password/phrase. Again, depending on your environment, you might be able to consider some form of key stored on the client, e.g. a certificate in the user's certificate store / keyring, or even stored in a protected configuration file; a key based on biometric data (not easy but i've seen this done successfully, though it has its own set of issues), out of band key distribution (e.g. via cellphone), etc. This would enable you both to use strong keys, prevent the server from accessing those keys, not require the user to remember two keys, and doesn't re-use a single password for different usages in different contexts.
like image 54
AviD Avatar answered Dec 28 '22 07:12

AviD