Password Storage

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Nov 26 23:42:21 PST 2015


On Fri, Nov 27, 2015 at 03:09:38AM +0000, brian via Digitalmars-d-learn wrote:
> On Friday, 27 November 2015 at 02:05:49 UTC, H. S. Teoh wrote:
> ...
> >At no time is the password ever sent over the network, encrypted or not.
> >
> >--T
> So, I understand what you are trying to say, but I'm stuck on the
> specifics of implementation, if you'll bear with me.
> 
> >For authentication, the password shouldn't even be sent over the
> >wire.  Instead, the server (which knows the correct password) should
> >send a challenge to the client
> 
> So my app is web based, so I don't really have a "client-server" model
> you are suggesting.
> I'm building it using Vibe.d with a mongodb backend, so hopefully the
> "client" will be a web-browser (or in future iterations, a mobile
> device - let's ignore that for now).

In this case, the "client" would be the web browser. I'm not too
familiar with what a web browser might provide javascript on the page,
but if javascript has a standard hashing function that could be used for
this purpose.


> >random number produced by a good RNG -- which is different each time
> >the user authenticates)
> I'm not sure why I need this, so I'm going to break down and example.
[...]

Based on others' reply, maybe the approach I'm suggesting may not be the
best implementation for your case, but in any case, here is how it would
work:

1) The server stores password01 in the user database.

2) A client (browser) connects to the server and claims to be a valid
user.

3) The server generates a random number, let's call it X, and sends X to
the client. (X is the "challenge".) This is done each time somebody
tries to authenticate with the server (the value of X will be different
each time).

4) The client receives X, prepends it to the password that user types in
(presumably the same as password01). The client then computes hash(X +
pasword) and sends the result, let's call it Y, back to the server.

5) Meanwhile, the server also computes hash(X + password01), and obtains
a value Z.

6) The server receives Y from the client, and compares Y with Z.

If Y==Z, then it proves that the client knows the correct password, even
though the password itself is never transmitted over the network,
because the only way the client can know the value of Z is if it knows
the correct password (the user entered the correct password) and does
the same computation as the server.

If Y!=Z, then the password is incorrect and the server rejects the login
attempt.

The reason for step (3) is to prevent replay attacks: if the challenge
is always the same, then a man-in-the-middle attacker can capture the
packets between server and client, and replay the packets containing the
client's response to the server later, thus obtaining access to user's
account.  Since the server's challenge is a random number that's
different every time, the attacker won't be able to provide the correct
response by replaying a previous correct answer.

The reason for step (4) is to prevent an eavesdropper from recovering
the password by man-in-the-middle attacks. If the password is sent in
plaintext, an attacker that compromised a router between the client and
the server (or runs a transparent proxy masquerading as the real server)
would be able to read the password off the packet while it's in transit.
Even if the password is sent in encrypted form, an attacker who obtains
a copy of the ciphertext could run brute-force attacks to recover the
plaintext password. By only transmitting a hash (presumably a 1-way
hash) back to the server, even if an attacker somehow manages to get a
hold of the hash value, it won't actually reveal the password.


T

-- 
The irony is that Bill Gates claims to be making a stable operating system and Linus Torvalds claims to be trying to take over the world. -- Anonymous


More information about the Digitalmars-d-learn mailing list