-1

I'm developing a program which needs users to login. The traffic is not sensitive but has to travel as fast as possible, therefore I am not securing the connection though TLS or something. The only sensitive thing is the password and probably the username (which will be the email address). I thought about either hashing the password on the clientside before transferring it or encrypting it with a RSA public key, the problem is, if an attacker can get this hash or encrypted password, he can easily just login using this hash directly if he modifies the client, so I need some sort of salting. The problem is: The server will store the password salted + hashed, so when the client hashes the password with a different salt each time,it will produce a different hash. With encryption the server can just decrypt the password+salt and strip the salt. Now I'm wondering is there a way without encryption, with only hashing, that I can transport my password securely to the server and prohibit an attacker to just reuse the hashed password?

My thoughts:

The Server stores the password salted with salt1, hashed. The server sends salt1 and a random (each connection a new) salt2 to the client. The client salts and hashs the password with salt1, salts and hashs the hash from step 1 again with salt2, sends this hash to the server. So to check the password the server has to salt and hash it's stored hash with salt2 and check for equality. Is this secure?

  • 2
    Does the connection to the server provide state? Define "as fast as possible" (e.g. why are you bothering with tcp if performance is the only consideration). What are your criteria for secure? Do you control the network between the client and server? Whats the worst that could happen? Why is protecting the confidentiality of the password important but the content of the message not important? Too little information to make an informed guess about what would appropriate here. – symcbean Aug 16 '16 at 22:49
  • 2
    HTTP/2 (SPDY) with TLS is actually faster, by a significant margin, than plaintext HTTP. – Polynomial Aug 16 '16 at 23:12
  • It does provide state, it's a binary protocol, the TCP connection will be kept. The message(s) do not need to be secured as everybody could potentially get the same information anyway. It's comparable to a game client/server (it's not a game though), where everyone can see anything but only the owner should be able to actively move his character himself. All traffic (move me to XYZ) doesn't need to be secured as any other connected client will see the change anyway. – tkausl Aug 16 '16 at 23:39
  • I'm not actively against encrypting traffic but is it really premature optimization if I don't encrypt as this is not time I waste to optimize? As I said, the data is publicly accessible, the login is only to authenticate the owner when he sends a command to the server. – tkausl Aug 16 '16 at 23:40
3

You can use the same technique as HTTP Digest Authentication (actually you could use exactly that technique, re-using any of several existing libraries).

The server send a challenge, the client answers by (e.g.) hashing together the challenge and the secret. The server takes care never to reuse a challenge.

Depending on the mechanics of the connection, you might need to re-authenticate the connection at every request. To reduce overhead you might want to use some kind of incremental nonce, i.e.

client                     server
login request ------>      user's password is "squeamishossifrage"
          <--- 12345       challenge
hash      (MD5("12345:0:squeamishossifrage")
          <--- OK ---
          ---> MD5("12345:1:squeamishossifrage")

Using HTTP with Digest-Auth this is done automatically. Using plain HTTP you might simply add a header or a parameter to each request.

The Server stores the password salted with salt1, hashed. The server sends salt1 and a random (each connection a new) salt2 to the client. The client salts and hashes the password with salt1, salts and hashes the hash from step 1 again with salt2, sends this hash to the server. So to check the password the server has to salt and hash it's stored hash with salt2 and check for equality.

This is OK, but it is equivalent to storing the password in the clear. For all intents and purposes, knowing the salt1-ed password is enough to perform a successful login; this means that if one were to gain access to the password database, he could use it as is without needing any decryption.

You do have an advantage over storing the passwords in the clear, and this is that this way you needn't worry against password reuse (i.e. the user uses a password which is the same as his password for another service. Anyone gaining access to your database also gains access to this other service).

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.