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