Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I am building a web application which requires users to login. All communication goes through https. I am using bcrypt to hash passwords.

I am facing a dilemma - I used to think it is safer to make a password hash client-side (using JavaScript) and then just compare it with the hash in DB server-side. But I am not sure this is any better than sending plain-text password over https and then hashing it server-side.

My reasoning is that if attacker can intercept the https traffic (= read plaintext password) he can for example also change the JavaScript so it sends the plaintext password alongside the hashed one - where he can intercept it.

The reason against hashing client-side is just ease of use. If I hash client-side I need to use two separate libraries for hashing. This is not an unsurmountable problem, but it is a nuisance.

Is there a safety gain in using client-side hashing? Why?

Should I also be using challenge-response then?

UPDATE: what interests me the most is this - do these techniques (client-side hashing, request-response) add any significant security gain in case where https is used? If so, why?

share|improve this question
stackoverflow.com/questions/3715920/… –  amal Nov 2 '11 at 10:17
Thanks for the link, but while the situation is similar, there is a subtle difference - I am using https. Also, I find explanation of the answers lacking... If page can be read, it can also be modified, which means the user will enter his password in a form which was supplied by attacker. I will update the question to better emphasize this. –  johndodo Nov 2 '11 at 10:34
add comment

migrated from stackoverflow.com Nov 2 '11 at 12:06

This question came from our site for professional and enthusiast programmers.

4 Answers

up vote 11 down vote accepted

If you hash on the client side, the hashed password becomes the actual password (with the hashing algorithm being nothing more than a means to convert a user-held mnemonic to the actual password). This means that you will be storing the full "plain-text" password (the hash) in the database, and you will have lost all benefit of hashing in the first place. If you decide to go this route, you might as well forgo any hashing and simply transmit and store the user's raw password (which, incidentally, I wouldn't particularly recommend).

share|improve this answer
Can you please elaborate on why you think this is so? AFAIK the only advantage to using hashed passwords is protecting users' accounts on other websites in case the passwords / hashed passwords are stolen - nothing else. If this is so then there should be no difference where the hashing is done. Is there some other advantage in hashing that I have missed? –  johndodo Nov 2 '11 at 12:35
Storing a salted hash is actually supposed to help protect your application against an attacker gaining credentials by reading the authentication data store contents. If he can't infer a password from the store, he can't pass it to the server for authentication. –  Nicole Calinoiu Nov 2 '11 at 13:06
Aaaah,that makes sense... Attacker gets hold of hashed password, but he is not able to use it on this system because the system hashes it by itself - so he would have to find the original password first. Nice one! :) –  johndodo Nov 2 '11 at 13:20
Yes, the hash of the password becomes the authentication token - but if this can be intercepted then so can the session identifier. Although the latter would only allow the session to be abused, while the former allows the attacker to open new sessions, the proposed advantage is not really that great and predicated on a MITM attack on the SSL connection. –  symcbean Nov 2 '11 at 17:19
@johndodo "the only advantage to using hashed passwords is protecting users' accounts on other websites in case the passwords / hashed passwords are stolen" Not only one reason. But still, it is one reason. –  curiousguy Nov 4 '11 at 0:52
add comment

I find all your concerns sound, but my recommendation would be to do it server-side.

There's always a fairly big chance that a user will leave their terminal unlocked, allowing manipulaton. And also; if your hashing logic is client-side you're exposing it.

Another option would be to generate the passwords server-side; then you're not sending in a clear-text password. But you'd still need to communicate the password to the user. And since most users still don't use encrypted email, I consider that less secure.

I've seen solutions to send passwords through an encrypted tunnel to a cellphone; but I doubt the security is better than the SSL. Perhaps someone could prove/disprove this?

share|improve this answer
"if your hashing logic is client-side you're exposing it." so what? –  curiousguy Nov 4 '11 at 0:53
Perhaps not a big deal. But I prefer exposing as little as possible. Let's say you'd get hold of a database with hashed passwords. If you know the hashing algorithm, you could generate a list of hashes from a list of common passwords, and match these. –  rmorero Nov 4 '11 at 9:37
@rmorero: I tend to disagree... First of all, there is not much you can do to protect against user leaving terminal unlocked, apart from sonar and similar. Also, hiding hashing algorithm is security by obscurity. You have to decide what is secret and what is not. Hiding non-secret things is usually counter-productive. –  johndodo Nov 7 '11 at 6:36
@johndodo True, these are valid points. And my logic above partly depends on a bad implementation. Still, I would claim that security by obscurity is only counter-productive if you're relying on it; which I do not recommend. –  rmorero Nov 7 '11 at 8:33
@rmorero: the danger in security by obscurity is not that much in relying on it... As I see it, the three major problems are: a) you spend your time on it instead of on real solutions, b) you could make an error and actually make security worse, and c) it makes the system less transparent and might thus hide other errors. In other words, it adds "fog" - and since a skilled hacker probably has fog lights in his arsenal, I would prefer a sunny day to face him. ;) –  johndodo Nov 8 '11 at 20:18
show 2 more comments

If you are in https tunnel,
passwd | hash should be secured from ethernet surveillance.

On client side maybe you could salt hash with session id.
This could be harder for malicious js to simulate.

share|improve this answer
Its worth noting that the fixed+challenge salts with client side hashing can be used to implement a secure password mechanism over non-encrypted connections (but opbviously the session token and other subsequent exchanges are not secure) –  symcbean Nov 2 '11 at 17:21
@symcbean What do you mean by "secure"? –  curiousguy Nov 4 '11 at 0:54
I mean that the password transmission mechanism is not subject to eavesdropping. –  symcbean Nov 7 '11 at 11:58
@kwolbert you keep posting comments as new answers instead of comments. Would you please attach this as a comment where you mean it to be read in context and then delete the answer here? Thank you. –  Jeff Ferland Aug 29 '12 at 19:07
@kwolbert Welcome to IT Security! Please use the Post answer button only for actual answers. You should modify your original question to add additional information. –  Scott Pack Aug 29 '12 at 19:31
show 1 more comment

Hashing on the client makes sense only if you do not trust the server in some way, and do not want to show it the "actual" password (the one which the human user remembers). Why would you not want to show the password to the very site on which the said password has any use ? Because you have reused the password elsewhere ! Now that's usually bad, but there is a relatively safe version which is incarnated in myriads of browser extensions or bookmarklets such as this one or that one (I don't vouch for their quality). These are tools where the human user remembers a "master password", from which a site-specific password is generated, using the site domain name as a kind of salt, so that two distinct sites get distinct passwords.

While this scenario makes sense, doing it with Javascript sent by the server itself does not. Indeed, the point of hashing the password client side is that the server is potentially hostile (e.g. subverted by an attacker), and thus Javascript code sent by that server is, at the very least, suspect. You do not want to enter your precious password in some hostile Javascript...

Another case for client-side hashing is about slow hashing. Since passwords are, by definition, weak, you want to thwart dictionary attacks. You assume that the bad guy got a copy of the server database, and will "try passwords" on his own machines (see this blog post for some discussion on this). To slow down the adversary, you employ an inherently slow hashing process (such as bcrypt), but this will make the processing slow for everybody, including the server. To help the server, you might want to offload some of the work on the client, hence do at least part of it in some Javascript code running in the client browser...

Unfortunately, Javascript is awfully slow at this kind of job (typically 20 to 100 times slower than decent C code), and the client system will not be able to contribute a substantial part to the hashing effort. The idea is sound but will have to wait for better technology (it would have worked with a Java client, though: with a decent JVM, optimized Java code is about 2 to 4 times slower than optimized C code, for a hashing job).

To sum up, there is no really good case for doing client-side password hashing, from Javascript code sent by the server itself. Just send the password "as is" to the server through an HTTPS tunnel (the login page, the form destination URL, and whatever page are protected by the password, shall all be served over SSL, otherwise you have more pressing security issues than the use of passwords).

share|improve this answer
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.