views:

174

answers:

4

Let's assume I must have user's sensitive data that was optionally encoded on the client side.
Encryption (optional) should be done with user's passphrase.
User login (optional) should be done with user's password.

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

My options and their drawbacks:

1. No authentication, Client-side authorization:
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 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 more 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: 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 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 kind of a login and/or password or a token (may be unique URL).

+1  A: 

Use option one and make the URL for the data contain a long random string. Anybody who knows the random string can get the data. Of course, only the client who created the data is going to have that URL right off.

If someone wants to give someone else revokable access, allow them to generate a new random URL and provide a means for them to name that random URL and revoke its ability to get at the data.

Capability based security is easier to get right, more flexible and makes more sense to users. There is a really excellent YouTube video about capability based security and a nice website with some essays about it.

Omnifarious
I've though about this option too, but the issue of someone loosing the URL is very problematic. I even thought about sending the URL by email to registered email address. But still I can't afford to loose the data is someone lost the URL and his email box is not accessible.
Vitaly Polonetsky
@Vitaly Polonetsky: Of course, they could lose the password too. :-)
Omnifarious
+3  A: 

@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.
AviD
Another side point, is that the user's password should never be stored in plain text, but rather hashed. However, using the password as an encryption key would require using it as plain text! Also, changing the algorithm whilst re-using the same password will not help, do not forget Kerckhoff's law.
AviD
@AviD: Thank you very much for the answer. The password will never be stored in plain-text in DB (That's really dumb and I don't understand how major companies can allow that - Until they are hacked :) For example if I store SHA1 hash of the password and user data is encrypted (on the client-side) using the same password in say RSA encryption, what happens if the DB gets hacked ? Can the hacker reveal the data, based on the fact that the key is used twice (once as data and once as encryption key).
Vitaly Polonetsky
@Vitaly, you are actually raising two very good issues here: 1. are there cryptanalysis attacks that can leverage re-use of the same key (or, data encrypted with a key, AND the key available in hashed form)? I really don't know, but I think that a good strong SALTED hash should be protection enough on the encryption key.
AviD
The second issue, which is actually more interesting, are there other issues around sharing the key? For example, what if the badguy can bruteforce the login page, thus discovering the password/key. Or, if you use a simple hash and badguy has db access, can he rainbow-table his way into finding the user's password/key? Obviously, these two can be prevented (strong password policy and limiting bad logins via lockout mechanism for the first, and using a SALTED hash for the second), but it does show the potential can of worms here.
AviD
(continued) E.g. a malicious admin can sniff/debug the users password during the login process, before the hash. Also, what happens when the user wants/needs to change his password? Are you really going to rekey all his data? Of course, there are more strategies to get around these issues too, but there is really no good reason to do this. Encryption keys and passwords should always be single-purpose.
AviD
I think passwords and authorization are overrated in the extreme, and they are much more complicated to get right than most people think.
Omnifarious
@Omnifarious, I agree with you on the second point, and on the first half of the first point: passwords are indeed problematic, yet they are (unfortunately) still the best available option in many cases. Authorization, on the other hand, I find to be UNDERrated and UNDERutilized, usually because it's not correctly understood. All that said, it doesnt change the fact that you still need SOME kind of authentication, and you need to restrict access on the server.
AviD
@AviD - You don't in fact need any kind of authentication. It's a myth. I'm perfectly happy to put up URLs to private data that are publicly accessible, as long as they are longish random strings. The OS the browser is running on is already authenticating its user, and the browser's bookmarks file is protected by that. Why does your website need yet another password and more authorization than that?
Omnifarious
@Omnifarious - really? How about we start with internet cafe's? Round it out with a nice helping of insecurely configured systems topped with ~60% Windows/Administrator/blank password combos, a side helping of shared machines, and a steamed any number of scenarios where you dont want your corporate domain admin gaining access to your private data stored outside the network. We can wash it down with false assumptions that bookmarks file is ALWAYS protected by the OS, and for dessert we can always try bruteforcing the URLs (since you can't lockout the user for a wrong URL). Still hungry?
AviD
@AviD - Bookmarks files are no more secure than passwords in an Internet cafe setting. It's trivially easy to get a key logger onto one of those machines. The corporate domain admin issue is addressed by using SSL, though to really solve it you need to alter the browser to remember the certificate it got last time for a site and complain if you get a different one. And if your bookmarks file isn't secure on a corporate domain, neither is a password.
Omnifarious
Oh, and brute forcing the URL when you're using a 256-bit cryptographic random number to generate it... *laugh* If someone can do that, then we have many more problems than URL brute-forcing.
Omnifarious
@Omnifarious, wrt security on a corporate domain, by definition you are not secure FROM the corporate domain - i.e. the domain admin (unless you're taking specific precautions such as EFS, but not usually relevant to bookmark files). I also agree about BF'ing 256bits (even though it IS technically possible just not feasible), though that's assuming you do that right - and not just use trivial GUIDs (as I see often recommended here). Also, wrt to passwords in a corpdomain - dont forget these are passwords for an *external* service.
AviD
A: 

@Vitaly

Probably best to clarify some terms first. Then I will give you what I think to be the best move in your situation.

First, as @AviD mentioned, it is probably best to clarify what you mean by Authentication and Authorization. The two are distinct terms and play very different roles when it comes to securing applications. Taken from this blog post on Authentication vs Authorization:

Authentication is the process of verifying that a user has the right to access an application.

Authorization determines what actions a user has the right to take within an application.

That said, let's turn to the question of data security. Use the HTTPS protocol to secure network traffic between your server and the user's client. In addition, think about hosting your data, business logic and user interface on completely separate servers (multi-tier). Or at the very least, don't expose your application to a web accessible directory.

You didn't give much detail to the nature of the data you're trying to secure, but let's assume you're talking about credit card data. Consider storing that data on a separate server on your LAN that is not connected to the "outside world." Then use a token-key system to both link and dissociate the credit card data from your main data repository. Then your application would only have access to meaningless tokens, instead of the actual sensitive data.

Finally, I would strongly advise against using an un-authenticated unique url as a means for the user to access sensitive data. Even if the url is random, if someone or a bot can just guess at the URL, what's the point of even discussing security?

Sean Williams