0

Assuming SSL/TLS cannot be used in this context, is this method secure enough to authenticate someone without someone listening to be able to retrieve the password from the information transmitted.

  1. The client sends a login request.
  2. The server replies with a unique identifier for the login
  3. The user enters in the password
  4. The client hashes the password and encrypts the identifier with the hashed password(encryption(value: identifier, key: hash(password)))
  5. The client sends the encrypted identifier + the username
  6. The server receives the encrypted message gets the decryption password from the database using the username the client provided and checks if its able to retrieve the identifier using the password.
  7. If the identifier is successfully retrieved by the server authentication is successful.
  • 2
    If the server gives the client the code that does step 4, then it's trivial to defeat with active MITM. – domen Aug 5 '14 at 8:43
  • @domen This scenario is about a program not web app so the code cannot be altered that easily. – user36976 Aug 5 '14 at 8:48
  • @Nick a MiTM can intercept the client's response with the encrypted password and send it to the server first. And why is it that the code could not be altered? – Steve Dodier-Lazaro Aug 5 '14 at 8:52
  • @SteveDL domen was saying that if it was a webpage a MiTM can easily change the authentication code, but in this scenario the code cannot be changed by MiTMs. A MiTM can intercept the response but they would then need to bruteforce the encryption which would mean also bruteforcing the hash, and it also cant be used to resend the same packet to authenticate because the identifier will be different per login request. – user36976 Aug 5 '14 at 8:55
  • @Nick if the MiTM can intercept the packet you send (whatever the form) and send another one instead, they can change the code. – Steve Dodier-Lazaro Aug 5 '14 at 8:57
2

The answer is no.

The server replies with a unique identifier for the login

This step in itself contains a flaw. A MITM can simply intercept this response, change the unique identifier and observe how the client sends the encrypted identifier + the username. If the attacker has pre-computed rainbow tables for whichever unique identifier is injected, then gaining the password is trivial.

1

This is barely more safe than transmitting the plaintext password.

Of course the encryption algorithm would have to be resistant against known plaintext attacks, but this is not a problem (AES is).

But even if a MitM would not be able to directly calculate the password from the ciphertext that he wiretapped, he could easily run an offline dictionary attack and just try a lot of password hashes until he successfully decrypts the identifier. The usual method of salting passwords to make dictionary attacks inefficient does not work here, since both server and client (and thereby the user) would have to know the salt.

  • It's not safe, but still more than barely more than a plaintext password. The encryption occurs with a key the size of the hash function's output, so a fairly large space. If client and server agree to using a salt (the site's exact domain name for instance) then the rainbow table must be computed per site, slowing down table generation slightly. If passwords are weak the hash function should be slow so the attacker doesn't iterate over password space and does encrypt(..., hash(<iterate here>)). – Steve Dodier-Lazaro Aug 5 '14 at 8:57
  • Still, that's one rainbow table per domain. Given the MitM can intercept logins and the passwords are used for extended periods of time (website password usually are) the attack is quite efficient for one domain. But you are right, salting the password will make the attack harder. It should better be per-user salts, though. – kllmnn Aug 5 '14 at 15:31
  • Make it an OTP then :) – Steve Dodier-Lazaro Aug 5 '14 at 18:24
0

If you control the application the client has why not embed a public key in the client and use that to encrypt the login details? It would be difficult to replace the key etc. but it would be simple and robust - especially if you have a secure distribution channel for the original software install to prevent the key being changed.

If you really had to find a way I believe this would work:

  1. Client sends username to server
  2. Server calculates HMAC(usersHashedPasswordFromDB, randomToken)
  3. Sends result to client along with login form
  4. Client Calculates HMAC(slowHash(password), randomToken)
  5. Client checks (2)=(4)
  6. Client knows randomToken has come from someone who knew the hash of their password - the server
  7. Client Calculates quickHash(slowHash(password)+randomToken) (slowHash cached from earlier)
  8. Client sends hash to server
  9. Server calculates quickHash(usersHashedPasswordFromDB+randomToken) and compares to supplied hash

Where quickHash() is a fast secure hash implementation and slowHash() is a suitable function with salt and work function that is the same on client and server - possibly using domain and username as the salt for example.

You would still be vulnerable to a dictionary attack as the only secret is the user's password - but this can be mitigated by server side lock-out or back-off on failed attempts (though this poses a denial of service risk).

Happy for input and comment / corrections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.