views:

129

answers:

4

Here is what I got for a webapp login scheme. Present in database would be two salts and hmac(hmac(password, salt1), salt2).

When the user go on the login page, he gets salt1. If he has javascript activated, instead of sending the plaintext password, it would send hmac(password, salt1). If he does not have javascript, the plaintext password is sent.

So, on the serverside, when getting a login request, we'd first check what is sent (passwordSent) against hmac(passwordSent, salt2). If it does not work, we'd try hmac(hmac(passwordSent, salt1), salt2).

Someone getting access to the database should not be able to login with the password hashes and I don't think (but I may be wrong) that multiples hmacs diminish the hash resistance. Do any good crypto expert see any obvious error I may have done ?

+5  A: 

This looks a little like security through obscurity, what is the point of using javascript to hash the password on the client side if you still accept plain text password from the client?

You didn't mention if this was over https, if you aren't using https then you may as well have no passwords at all. If you aren't running https then any MITM can see the salt you are sending as well as the javascript used to hash the original password so you have nothing gained.

As for your concern about the possibility of hmac collisions between two salts, that is probably very unlikely (depending on your hash algorithm) and how secure you keep your salt values. Even with MD5 that has had some collision attacks discovered and has a set of rainbow tables, you will be ok if you keep your salt very very safe.

Please, everybody, please stop trying to implement custom crypto systems unless you have a background in cryptography. You will screw it up. --Aaronaught

Well said!

Harley Green
The point is to not have a plain password going around if the client has javascript enabled but still let users who don't like js to log in. If they have js they'd get a little more security, if they don't it's not worse than current situation. Some clear indication when javascript is not activated should help (à la SO).It should be over https but it does not prevent MITM attacks if the user is using an hostile local network. The attacker would have the salt used but I see only two attacks he could execute : bruteforce the hash he gets back, or replay the password sent later.
Arkh
@Arkh: I think we've answered your question. Exactly what attack vectors do you think this approach prevents? You're performing graceful degradation of what is essentially a no-op in security terms.
Aaronaught
The vector I'd like to reduce is clear password interception. Even if the attacker control everything between the client and the server.
Arkh
But you don't achieve that with this scheme... Unless the client generates the salt totally randomly and independent of the server then the attacker in between the client and the server can see the code you use to generate the hash, see the seed, and then can with much higher probability crack the password using chosen plain-text attacks.Secondly, they could launch a replay attack and gain access to the system without knowledge of the user's password
Harley Green
Thanks, I totally forgot about the attacker giving chosen salt to attack the hashed password. Https here I come.
Arkh
+1  A: 

Probably obvious to you already, but you're effectively letting people log in with two different passwords in that setup.

If you want to give people the option of sending their passwords with encryption, I wouldn't tie that to anything strictly client-side, and just force HTTPS, as Harley already implied.

pinkgothic
A: 

You might want to look at HTTP Digest authentication. That is a standardized protocol which avoid clear text password in any case.

deamon
No IE6 :/.But I'll read a little more about it as it's very interesting.
Arkh
+4  A: 

Sounds pretty far-fetched to me. If the objective of this is to prevent a "man-in-the-middle" attack by virtue of the plaintext password being sent over HTTP, then use SSL.

Hashing on the client side accomplishes nothing; unless the salt is actually a nonce/OTP, and not stored in the database, then a man in the middle can simply look at the hash sent by the original client and pass that along to the server. The server won't know the difference.

If this is supposed to make it harder to crack if someone gets hold of the database, it won't. If the hashing function is cheap, like MD5, this won't be any more difficult to crack than one salt and one hash (in fact it's actually weaker, since hashing is a lossy function). And if you use a strong hashing function like bcrypt, it's already good enough.

Please, everybody, please stop trying to implement custom crypto systems unless you have a background in cryptography. You will screw it up.

Aaronaught
"Please, everybody, please stop trying to implement custom crypto systems unless you have a background in cryptography. You will screw it up."Yeah, that's why I ask about blatant screws up before implementing anything.
Arkh
Even if all the experts on this site were to give their two cents, it is still not enough to certify your system/scheme "secure" just because you have the "communal approval" from stackoverflow.comNothing beats rigorous mathematical proofs of encryption scheme security. See: "perfect security" and "semantic security".
Harley Green