I have wondered many times why we still send the password over the wire (even if in SSL). It should be hashed with a salt every time before being sent! A lot of people reuse their passwords, the user shouldn't trust the website to hash it.
Because calculating the salted hash on the client side will just substitute the hash for password and render the whole hashing useless. Also it would require additional roundtrip to server in order to get the stored salt.
Then there is the UX problem where mechanism like that would have to be implemented on the browser level (and in fact it is as Authorization: digest is mostly what you are proposing) which according to some leads to “ugly and confusing” UI.
> Because calculating the salted hash on the client side will just substitute the hash for password and render the whole hashing useless.
I don't understand what you mean. Just in case I didn't make myself clear, I don't mean substituting the hashing on the server, I mean adding it on the client.
> Also it would require additional roundtrip to server in order to get the stored salt.
It could be salted with some constant/domain name.
> Then there is the UX problem where mechanism like that would have to be implemented on the browser level
What I am saying could perfectly be done with javascript, although I don't see why browsers could not integrate it too.
> which according to some leads to “ugly and confusing” UI.
I am completely lost, I am not sure if you understood me but I don't understand what you mean. Can you explain yourself further or provide a resource that explains this UX problem you're talking about?
The first two points have to do with the fact that if you do the whole process only with symmetric primitives you are only spliting the traditional salted hash into two computations one of which then becomes essentially redundant. If client uses deterministic salt, then whatever you send over the wire is equivalent to password and constant for every authentication. If server sends random challenge which is then hashed by client together with something derived from users password then whatever value that is stored on server in order to check validity of the response is sufficient to fake the response (and also essentially equivalent to plaintext password as it has to be derived from it in some deterministic manner independent of the random salt/challenge). That is to say, the protocol has to be somewhat more complex than that and involve asymetric cryptography to solve both of these issues at once.
There is no technical reason why this could not be implemented in pure JS (and there is lot of things that do something like that with varying complexity and security properties). But there is the question of exactly what is the threat model where the server is trusted to provide implementation of code that defends against compromise of that exact same server.
And as for the UX/UI issue of browser-based security: for security features like this to be truly secure the user has to be sure that he is interacting with the native browser/OS UI and not with something that can be intercepted by JS (or some other untrusted code). This is the reason why various parts of browser UI cannot be hidden, why legitimate permission popups overlap browser toolbar and the idea behind Ctrl-Alt-Del in Windows NT. Such UI by design cannot look as part of your website/application which both confuses even technical users and annoys marketing people because of added friction.
Also what didn't help adoption of any kind of more secure authentication for public facing websites is that in IE the resulting UI was ugly, inconvenient and in some cases downright broken (eg. dialog box used to confirm that you really wanted to use certificate from PKCS#11 token not only didn't say what for, it didn't say anything except “Error! Yes/No”).
> If client uses deterministic salt, then whatever you send over the wire is equivalent to password and constant for every authentication. If server sends random challenge which is then hashed by client together with something derived from users password then whatever value that is stored on server in order to check validity of the response is sufficient to fake the response (and also essentially equivalent to plaintext password as it has to be derived from it in some deterministic manner independent of the random salt/challenge)
You seem to misunderstand the purpose of what I am proposing. I am not proposing this scheme as an alternative to what's proposed in the blogpost.
I am proposing this procedure as an extra protection step for password reuse. If you were to run an exploit on the server that reads its memory contents, you may find a user "Admin" that uses the password "FavoriteFood-DateOfBirth".
If you sent the original version of that password, then such an attacker will find real-world information about you. That information can be used to exploit your identity on other websites. If the password is hashed, then that information doesn't get leaked. Sure, you can fake your authentication to this server, but you have not gained real-world information about your target.
Without salt, the attacker can fake the authentication on every service where that password gets reused. But with salt, every server sees a completely different password on their end. Essentially, your hashed password with salt has become your new password in the server's eyes.
> : for security features like this to be truly secure the user has to be sure that he is interacting with the native browser/OS UI and not with something that can be intercepted by JS
Yes, you were one step further than me on this front. I do agree that communicating this to the user is non-trivial.