I already know I"m going to hash the user's password n times in either sha512 or n*x in sha1 before it is sent to the server. Once at the server, I'm going to use bcrypt set to use ~1/100th of a second. Before I move on, onto my reasoning behind using sha512 instead of sha1, I'd like to state a few things. First, I know that client-side security is a joke. Second, I know that a Man-in-the-middle attack could strip the page's javascript of the hash function. Finally, I realize that this will mean that people will not be able to login without javascript being enabled.

I am currently using sha512 set to use ~1s in ie8 [2], it is setup as such.

  1. Take the user's password and username.
  2. Add a static-nonce(to lengthen it really and nothing else).
  3. Hash it via the hashing function, in this case sha512.
  4. Take that hash, hash it via sha512 with the current loop number packed into a single byte.
  5. repeat step 4 n times.
  6. Once it is done, take that value, and put it into the password field.
  7. finally allow the system to POST to the server.

Now then, what is the advantage of doing n*x hashes of sha1 vs the n times of sha512. The entire point behind using this system is that, in the event of a database leak the attacker will have to increase the amount of time spent trying to find the password by z time. Also, by hashing it before it even gets to the server(along with using TLS), it makes it, so that, in the event of some weird bug, the password is never seen as plain text.

I believe that sha512 is a better choice since there is already broken sha1 and thus it's security is not worthwhile, but on the other side. The fastest javascript library I've found for sha512[1][] is ~50 times slower than native code, but the fastest sha1 library that I've found is only ~17 times slower than native code.

Thus it is a question of is the broken sha1 going to cause a greater loss in overall security and thus slowdown of an attacker than doing less iterations of sha512 which as of right now none of the sha2 family is remotely broken. Has anyone else dealt with this issue before?

[1]: that via fuzzing results in the same hash as the c implementation/php one results in the same hash for ~300 inputs.

[2]: One year after ie10 is out, I'd like to drop support for ie8 so that I can move up the number of hashes to something more reasonable.

  • Don't do this, really.
    – You
    Nov 1, 2014 at 10:34

2 Answers 2


This sounds a bit stretched, maybe counter-productive, sub-optimal and it doesn't really offer much added security. The "password" is actually seen in plaintext, because the password is the string you finally send in the place of the real password. What exactly are you trying to achieve?

In any way, if you are really trying to have the 'real' password 'not being seen in clear text' (and don't trust ssl) you should be looking at implementing a challenge-response protocol. This is usually the way one goes about if he does not want the password to be transported in the clear (or something resembling the password as in your case).

Now if you really want to go on with your plan, and still do that client-side trickery you describe, SHA-1 is perfectly fine for that. Even MD5 is fine and considerably faster. The 'talk on the street' about those functions not being secure is about collisions - which is something you probably don't care in your implementation. Also you can have a look at http://www.jcryption.org/ , it's a jquery library that does asymmetric encryption of html forms.

But, again, I strongly advise against this whole implementation.

  • The password is never seen. I don't know what you're talking about. The users password that they are giving to me is never seen. In the event of a databreach, the password is never seen and on top of it the time taken to get it is increase. They are broken, and pretty broken at that. Md5 is insanely broken, and thus I refuse to use it for anything. Sha1 is on its way to a full break, and thus I didn't really trust it. I do trust SSL but since they can say "I don't support encryption" a user could in theory, end up using a clear connection.
    – 133794m3r
    Jul 13, 2011 at 9:06
  • 4
    @133794m3r First of all, neither MD5 or SHA1 are 'insanely' broken. Read up on the attacks, it's just somewhat easy to find collisions, something you shouldn't really care about in your scenario. Second, the password in your implementation is just the hash. Third, if a user does not support SSL, he cannot get a clear connection if your server only offers the content over SSL (leaving sslstriping aside). Even so, the correct way to do such things is using challenge-response. Slowing down the client side is never going to offer any significant security and is not recommended.
    – john
    Jul 13, 2011 at 13:11
  • 2
    @133794m3r If you really want to go one with this, just hash your username-password pair just once or twice. Doing it multiple times using client-side javascript iterations offers nothing.
    – john
    Jul 13, 2011 at 13:13

The extra protection added by the client-side hash is extremely marginal. From the point of view of the server, the hash result is the password, because the server grants access to whoever is able to show that hash value, without requiring the actual password. In particular, if a "weird bug" results in making the hash value apparent to the attacker, then you lost: the attacker can simply connect to the server by showing it the hash value, without running your Javascript (average users may have trouble circumventing a bit of Javascript, but it would not be safe to assume that the attacker is not a bit more capable).

What protection remains is that if the attacker sees only the hash, he has not (yet) guessed the "real password" and will not (immediately) be able to try that password on other servers where the same user also has an account. This changes nothing to the security of your server but it could be viewed as a "community service".

As for the extra attack cost induced by the multiple hashing: although the idea is sound, using Javascript is not. Javascript is much slower than C or assembly. It takes one second with IE8 in Javascript, but nothing forces the attacker to run his attack in Javascript. He may use C, assembly, possibly a GPU. If you want to make dictionary attacks hard, you need to make the hashing slow for the attacker. By doing it on the client in Javascript, you prevent yourself from making as many iterations as would be needed to achieve proper security. One way to see it is the following: we want each "guess" to be slow for the attacker. Unfortunately, we cannot make it slow for the attacker unless we make it slow for the "honest system", too. So the performance of the honest systems (client and/or server) limits the amount of slowness we can inject. By doing it on the client in a suboptimal language, we artificially make the slowness burden much heavier for the honest systems and not for the attacker.

In practice, the attack cost will be that of bcrypt; the hashing will be negligible in comparison. This is especially true for SHA-512, which uses 64-bit integer operations, which are awfully slow to implement in Javascript, due to the lack of 64-bit integer types. So the precise answer to your question is: using SHA-1 (or SHA-256) would be "better" than SHA-512 if the goal is to induce slowness into dictionary attacks; but even so, the induced slowness will be negligible with regards to what server-side bcrypt does, so the question is kind of meaningless. On the other hand, 1s extra delay will infuriate normal users, who are known to have no patience.

  • This was originally done as a way to increase time required incase of a mitm so that it's not just plain text. The time required would be minimal but is still something. I'd love to have a native implementation of it in all browsers, but that's not likely to happen. The 1s is the maximum, and if they're using ie8 that's saddening.The other reason was to make sure that they cannot run away with other passwords. Since I think everyone should be doing this "community service." As it helps us all.
    – 133794m3r
    Jul 16, 2011 at 11:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .