3

I am developing a web application which stores encrypted data on a server. I want to derive the encryption key as well as the login key from a single user password, so I want to use libsodiums crypto_pwhash to generate a long enough key, that I can split in two. The idea is that the server cannot decrypt the encrypted data.

To use this function it needs a salt. I understand that the salt may not be secret, but it must be stored somewhere.

  • If I store it in the server, it must be retrieved before authentication (because it is needed to derive the login key). So this would allow for testing if a username exists without knowing its login key. I am unsure if that would be a security risk.

  • Could I derive the salt some other way? What if I would just hash the username? Or the password itself? Or would I run into the risk of not having enough entropy?

6
  • The usual procedure is to store the salt in the same database entry as the username and the password hash. If you then look up the user name you'll find the salt with which to process the password. This usually allows for random salts.
    – SEJPM
    Jul 14, 2015 at 11:42
  • @SEJPM: MMh, ok, but that is for storing a hashed password on the server, correct? If I understand correctly, normally the client sends its password to the server and the server tests it with a stored hash using the salt. But I never want to send the password to the server. I want to salt/hash it on the client side.
    – Nathan
    Jul 14, 2015 at 15:47
  • The password itself is equivalent to not using a salt at all. The username combined with your site name is decent. You can combine it with a salt stored on the server which the client can query before logging in. Jul 14, 2015 at 15:52
  • I am having a hard time understanding your proposal. Is the data encrypted with javascript in the browser? Then you want to use the same password for authenticating the user and client side encryption? A good process diagram might be helpful.
    – mikeazo
    Jul 14, 2015 at 17:00
  • @mikeazo I tried to clarify the question with my last edit.
    – Nathan
    Jul 14, 2015 at 20:31

3 Answers 3

1

The required property of a salt is to be unique, cause it make impossible to use dictionary table for reverse hash of all user with the same table.

The other usefull property is to be impredictable so attacker can't pre calculate dictionary table before obtening the salt.(scenario where this is usefull : the attacker detect a security problem he can use to obtain password hash, he generate a table for the username he want to access then when he obtain the password he can use it before you can react to the attack)

random salt give the two property.

Using site name + username give you the first property.

password give you nothing cause when generating a entry in your dictionary table you know the password (the one you are hashing).

If you store it on the server you can respond to request with invalid username by an random number of the same size of your random hash(this is only obscurity and absolutly no security)

2
  • Just one question: What would be the difference if I calculate the salt by hashing the username vs. retrieving the salt from the server by the username. In both case the salt is available as soon as the username is available, is it not?
    – Nathan
    Jul 15, 2015 at 12:58
  • i didn't think about that, and yes you are rigth. Jul 15, 2015 at 13:20
1

I think the way to go about this problem is to separate, as much as possible, authentication and confidentiality. The ideal way to do this would be to have two passwords, one for authentication and a completely independent one for confidentiality. The problem is, users are not ideal. Likely they would make the password the same or add some very predictable string to the end of the confidentiality string.

The other thing to remember is that since this is a web application, I'm assuming that all the computations are taking place in javascript that the server sends to the client. This makes your adversary model interesting. If you are trying to protect confidentiality from a malicious server, but allowing that server to send you code (javascript) that you will run and that will have access to the password, you really can't protect yourself from a malicious server. Nothing stops the server from sending you javascript that performs as expected but also sends the password to the server.

So, you are definitely in a quandary and I think without additional assumptions and a better defined adversary model, you cannot protect the confidentiality of the data.

0

If I store it in the server, it must be retrieved before authentication [...]

It would be retrieved at the same time as authentication, like

select salt, pw_hash from users where name = '@name'

You would use both salt and pw_hash to validate the password that the user entered. You still might want to be careful about leaking information about whether your select returned a record or not, but that isn't complicated by the salt.

Your situation is complicated because you also want to derive an encryption key from the user's password such that the server can't do the same. Part of the confusion is because the user has a single password that he can't give to the server but it must somehow be used to authenticate the user - and therefore whatever is sent to the server is not strictly speaking a password. But most of the time you are read about salting and hashing inputs they will be called passwords.

So let's break this into 2 steps. The user enters a password. For authentication, the user runs some KDF without salt and send the result "C" to the server. The server looks up the user's salt, hashes the salt and C and compares that to its stored hash. If successful, the server returns the salt (either the same or possibly a different one) to the user. The user combines the password and the salt using KDF2 to get his encryption key. If the two KDFs are different, or are tweaks of one another, the two keys generated will not be related.

1
  • You are talking about retrieving the password from the database? But that means the client must have sent the password to the server allowing it also to decrypt the data.
    – Nathan
    Jul 16, 2015 at 8:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .