Link to home
Start Free TrialLog in
Avatar of rpgeegange
rpgeegange

asked on

Salt as plain text

When using the PBKDF2, bcrypt to encrypt the password and sent through network as in this question Sending the Password over network, is it ok to send the salt used in the encryption process as plain text to the user ?
Avatar of MajorBigDeal
MajorBigDeal
Flag of United States of America image

No certainly not.
The whole point of salt is to make it more difficult to use rainbow tables to reverse the hash.  If you send the salt in open text that will make it very easy for an eavesdropper to hack in.
Avatar of ozo
Salt values are not usually treated as secret
http://en.wikipedia.org/wiki/Salt_%28cryptography%29
Yes, it is  definitely OKAY,  and the salt will still do what it is intended to do.

However,  if you are transmitting the hash over the network --   I would suggest keeping the salt secret:  to further increase the difficulty of  attacking the hash  to guess the password.

Instead of sending the salt, you could  generate a  "token"  associated with the user, and send that instead.

The token could be either a database key,  or something,  that is used to deterministically find the salt  on both the user and remote endpoint ----  assuming that the applications on both sides have knowledge of a shared secret.
Avatar of rpgeegange
rpgeegange

ASKER

How can generate a token. The user must only enter the user name and password. I don't wont to give the salt as the input.
Please advice.
ASKER CERTIFIED SOLUTION
Avatar of cristiantm
cristiantm
Flag of Brazil image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That's not how you check a password, the salt stays with the Authorization Service. The user only sends the hash of the password, the salt is added to the hash, that is hashed and then compared. You store the hash of the salted hash, and you store the plain-text salt next to the hashed salt., This is ok because the hash can't be reversed, but the same operation that it took to get to the salt+hash can be done.
password= 5f4dcc3b5aa765d61d8327deb882cf99
5f4dcc3b5aa765d61d8327deb882cf99 + salt1234 = dccabeb3f6456ee837aa141696452cc0
Store:
salt1234   dccabeb3f6456ee837aa141696452cc0
Then accept 5f4d.... and then add the salt, hash, compare. This is for the authenticator service to do, not the client. The client only sends the hashed password without the salt.
-rich
When using PBKDF2, that is done on the Authorization service, not necessarily the client. What you want to do it transmit the hash in a secure manner like in a challenge-response or like I indicated before using Diffle-Hellman.

The client is sending the hash of the user password, but to do that more securely you're back to your other question, how to send it securely. DH is a good way, PKI is another, Challenge Response can also be used, and as you know SSL as well.

PBKDF2 is the storage of the password, not the sending of it.
-rich
I agree rich, but what he is stryng to accomplish is protect the password over the network. And he could send it, the salt is not something to be considered secret. (Edit: while I was writing this you sent another answer about this ;) )

But the main thing the author needs to understand is that while he DO protects the original password by using a salted hash on the transport, his server does not care anymore about the ORIGINAL password and uses the hashed version of it for authentication. And the server will accept connections from anyone that knows the hashed "protected" version, not just the original password.

For the author... my suggestions is that you avoid this. If you really can not use SSL, use another authenticated Diffie Hellman  scheme instead. Anything on that will be better than keep trying to protect it over the network using hash based schemes, that are not meant for that.

A very simple sollution would be:

User (U) knows Server (S) public key (eg RSA) and trusts it.
U and S exchange Diffie Hellman key, where S signs its DH public part using his RSA private key and U verifies it using the server RSA public key. The signing is important so the user can check that the public part came from the server, not an MITM Attacker.
U uses the DH key obtained to encrypt his password and sends it to S
S decrypts the password, hashes it using a salt stored on his database and compares it with the stored salted hash.

That would be secure enough. You are *almost* simulating an SSL there, much simpler and with some attack points that SSL avoids, but its for sure much better than trying something purely hash based. Note that while an MITM attacker could pretend to be U and do a DH key agreement with the server, it would fail to known the password for the last step. Therefore you dont need to authenticate the U public part of DH. But you DO need to authenticate the server part.
PBKDF2 or BCrypt are secure algorithms for password storage;   it is not a secure system for protecting passwords in order to transmit them across the network for authentication.

Although it provides some protection;  Salt  and Hash,  is enough  information to attempt a dictionary attack on the password.
In terms of authentication protocol strength: this is not a secure situation.

For secure authentication;  you should use a secure authentication protocol, such as the SASL framework,  with a secure authentication method such as SCRAM,  or CRAM-MD5 over SSL.

SSL or TLS with  validated certificates on the endpoints,   can provide the security suitable for credential exchange.

Use of symmetric encryption with a secure shared key;  or digitally signing a message with an asymmetric keypair, and encrypting with the server's  trusted public key,
are some secure ways of exchanging  hashes of authentication credentials over the network.
I'm sorry i didn't mention this before, the Salt should not be known, it should remain secret. What is the purpose of the salt if it's known? You can compute a rainbow table knowing the salt, you can crack the password FASTER knowing the salt... the salt has to remain secret or as secret as you can make it.

If you know the salt, you don't have to guess it, and that cuts down on the time you need to crack the password. it should work as follows:
Client sends hashed version of password (H1)
Server receives hashed version of password (H1)
Server adds salt to hashed version of password and hashes that result (H1+S = H2)
Server checks for match against it's stored version of salt+hash (H2 = H2)
They now match, auth accepted.

There is no reason to send the salt or store the salt on the client, you only want the server to know of the salt. If you send the salt then you're only comparing H2 to H2, and the salt gains you nothing except it took a pico second longer for the client to calculate it.

Double-Salt might be one approach you can take to this, but I've not seen anyone do it yet. Send the client the salt to use in a PBKDF2 or bcrypt hash, send that hash to the server, the server has yet another salt it add's to that hash...etc... But with the client storing the salt, you still only need to guess the user's password because it's easy to get the salt. It sounds good, use slow hash to create the first hash and slow hash plus salt for the second hash, but since you could potentially get both salt values it is security through obscurity at best.

https://www.experts-exchange.com/Security/Misc/A_12386-How-secure-are-passwords.html
-rich
I mean the salt is not secret because if the attacker gets the salted hash, he usually gets the salt too, since the first has no use without the second. You usually do not take special measures to protect the salt, it is as protected as the salted hash is.

The problem here is not publishing a salt or not, deriving it, or whatever. The problem is that he is trying to use it for something it is not meant for being used. Hashed salt is not for transport. Using two salts does not solve what he is trying to accomplish, that is transport security.

I strongly agree with you that publishing the salt and the salted hash over the network makes brute forcing it easier than if the salt was not sent. But thats the only way to use it if you want to have salted hash to protect the password over the network, since you need the salt on both ends. And finally, that s why you do should not do it. Its not you should not send the salt: it is that you should not use hashed password for securing it on transport.
Yes and kinda... Salts are kept next to the passwords traditionally, they don't have to be but they are. Sniffing a hash should not give away the salt in any way.

The salt should not be a part of the client unless there is a double salt situation. Where the user inputs a pwd, the salt is used in the initial PBKDF2/bcrypt hash, and then sent to the Server. The server doesn't need the first salt as long the client keeps the salt constant with the same password. The server should add an additional salt to the hash it receives from the client. Then check to see if that matches it's own salt+hash.
This would make cracking slower in that you'd need the salt from the client and the password, plus the salt and hash from the server to check for a match. PBKDF2 and bcrypt are very slow, so two operations of them with a possibly unknown salt would be sloooow, but it's not as you've said session security. It's basically only making the password guessing twice as slow, because you cannot guarantee the safety/security of either salt. In this situation too salts don't need to be sent over the wire, the server doesn't have to "seed" the client, the client should be able to create it's own salt, then hash+salt the password, the server accepts that, salt+hashes that hash I guess.

While I think the "double-salt" would be slow, that doesn't make the rest of the session anymore secure. If you are only worried about the authentication, and not the rest of the session then all you've done is put up chainlink fence where a wall should be. An attacker might not be able to get into the room, but they can see everything that goes on in it.
-rich
But an attacker still can get into the room, even with double-salted hash scheme.

Attacker will watch you entering with HASH(Password,Salt), copy HASH(Password,Salt) and present HASH(Password,Salt) himself to authenticate. Server never cares about Password itself, just if the person knows HASH(Password,Salt).

Its as safe as just sending Password and compare it directly from the server point of view.

From the user point of view, of course, he probably prefers the salted scheme because it is just making this server insecure, but he still can use the same password in another service :)...