<<< Kara (Star Wars episode VIIa)

Home

dlvr.it fail >>>


a better way to handle passwords

Saturday,  01/23/16  03:44 PM

<rant type="Saturday afternoon">

A key challenge in client/server systems which exchange information over a public network is authenticating users.  Typically users are identified by a userid, and authenticate with a password.

For security purposes passwords should never be stored, and so generally the server stores a hash of the password.  This enables validation but not recovery; if a user forgets their password it must be reset.

Because public networks are insecure, passwords should never be transmitted over the network, instead, they should be hashed on the client.  In addition to eliminating any possibility that passwords could be captured in flight, this also means that any kind of server error would never reveal a password, since the server never even sees them.

Note: the popular oauth2 authentication mechanism does send passwords over the network.  So it's a standard, but it is not that secure.

Hashing passwords on the client is good, but it leaves the possibility that a hashed password could be intercepted and replayed.  To solve this, maybe the current time could be combined with the password before hashing it?  Call this H(T+P).  But can the server validate this?  It knows H(P), and it might be able to guess T (although synchronizing time is never easy), but H(P) and T don't yield H(T+P).

Okay, maybe the current time could be combined with the hash of the password?  Call this T+H(P).  Now the server can validate this pretty easily - still the time sync problem - but it is insecure; if T+H(P) is intercepted then T could be guessed, allowing H(P) to be isolated.  A new T could be combined with H(P) to enable a replay.

Maybe the current time could be combined with the hash of the password, and that could be hashed again?  Call this H(T+H(P)).  The server can validate this if it can guess T, because it knows H(P) already.  This is secure and makes replays impossible.

That leaves the problem of time synchronization.  This can be solved with a little extra complexity by having the client request the time from the server.  The server responds with an encrypted time value V which is opaque to the client.  The client combines V with H(P), and then computes H(V+H(P)) and sends that to the server.  The server can validate this easily, because it knows V and H(P).

So here's the better way to handle passwords:

  • Client prompts for userid and password
  • Client computes hash of password H(P)
  • Client requests time token from server
    • Server responds with time token V (encrypted and opaque to client)
  • Client combines token with hash of password, and hashes the result, H(V+H(P))
  • Client sends userid and hashed hash H(V+H(P)) to server for authentication
    • Server validates H(V+H(P))

It's actually not that hard, and nicely secure.  You're welcome!

Oh yeah, this is how eyesFinder's authentication works...

</rant>