It seems to me that if an attacker can intercept my login request (sent with HTTP POST), then he can replay it later, no matter whether I try obfuscate it or not.
What am I missing?
It seems to me that if an attacker can intercept my login request (sent with HTTP POST), then he can replay it later, no matter whether I try obfuscate it or not.
What am I missing?
I'm assuming that you are talking about additional hashing. So it would look like this:
Client --sha1(password)--> Server --bcrypt(sha1(password)--> Database
I think you are aware of this, but just to make it explicit: the transfer needs to happen via SSL to defend against eavesdroppers, hashing client-side would be no help against them at all.
Hashing or obfuscating a password client-side can be a good mitigation against password reuse:
Even if an attacker accesses the password in plaintext either in transfer or at the server, it would still be hashed, so an attacker cannot try the same credentials at other websites without first cracking the hash.
It seems to me that if an attacker can intercept my login request, then he can replay it later, no matter whether I try obfuscate it or not.
Yes. Hashing client-side doesn't add any security to your application, the only advantage is that it mitigates bad user behavior, which may affect other applications the user is also using.
Note that it doesn't even protect your application from password reuse, as an attacker that gained that users credentials from another application would just hash it and try that.
It also does not add any complexity to the process of cracking your stored hashes. An attacker would not try a list of hashes as input, but a normal wordlist, which they would first pass through sha1.
As tim wrote, it could help mitigating the effects of password reuse for users in a few cases, but if what you're thinking of is hashing it client side instead of on the server side, this would be a major design flaw.
https://en.wikipedia.org/wiki/Pass_the_hash
This problem plagues the NTLM authentication, where it's actually even worse than in the common Web application/service scenario, since hashes are often cached on systems other than the server handling your authentication.
Your sha1 password simply becomes the plain password for an eyedropper.
What I do is the following:
On the database, each password is encrypted with bcrypt and a salt. The salt is "public".
When the user log in, the following happens: -> client send username -> server reply with "salt" -> client generate a random nonce -> client send "bcrypt(nonce+bcrypt(salt+password)+time)+ +time+nonce" -> server check that the nonce hasn't be used in the last 5 minutes, then does the password check. It is done by comparing input sent from client with "bcrypt(nonce+dbvalue+time)". -> for non existing user, an honey salt is sent.
It's quite hard to hack, but requires Javascript client side for browsers.
Even if one is eyedropping, the bcrypt hash is hashed everytime with new nonce and time.
This answer is effectively easy to get wrong, so I made a diagram:
Also, see here why I add this extra layer even with SSL: https://blogs.msdn.microsoft.com/vbertocci/2005/04/25/end-to-end-security-or-why-you-shouldnt-drive-your-motorcycle-naked/
dbvalue
is bcrypt(salt+password)
, as otherwise your comparison wouldn't work. And this means that if I get access to the dbvalue
, I can just send you bcrypt(nonce+dbvalue+time)+time+nonce
and log in, without having cracked the users password.