50

There are many sites on the Internet that require login information, and the only way to protect against password reusing is the "promise" that the passwords are hashed on the server, which is not always true.

So I wonder, how hard is to make a webpage that hashes passwords in the client computer (with Javascript), before sending them to the server, where they would be re-hashed? In theory this doesn't give any extra security, but in practice this can be used to protect against "rogue sites" that don't hash your password in the server.

Martín Fixman
  • 618
  • 1
  • 6
  • 7
  • 19
    a hashed password sent in the clear is no better than a password sent in the clear if the server is just comparing hashes, man in the middle attacks love this kind of "security" –  May 17 '11 at 21:14
  • 3
    @Jarrod - it sounds to me, though, like different web sites using different client-side hashing algorithms would prevent the attack described by that comic. One widely re-used password becomes many different passwords through those differing hash algorithms. That client-side hash calculation doesn't prevent other kinds of security being applied - such as sending the hash through a secure connection. –  May 17 '11 at 22:26
  • One thing, though - why would a rogue site add javascript client-side password-hashing code that would prevent them from harvesting those passwords? Asking the black hats to block their own exploits seems, hmmm, what's the polite word... Anyway, as a standard browser security feature, it makes some sense to (non-expert) me. But not in javascript. –  May 17 '11 at 23:10
  • 1
    If the password isn't sent encrypted it doesn't matter what it is, it can be intercepted, and a convoluted password that isn't stored hashed isn't any more secure than `password`. –  May 18 '11 at 01:18
  • 1
    @Steve,@Jarrod: What are you defending against? To defend against attacks on communications, you need to have the client compute a hash of the password plus the current time and a server-generated nonce; this requires the server to know the password. To defend against attacks on the server, you've got to have the server only know a hash of the password; this makes it hard to defend communications. Overall, it's better when the client proves their identity using public key crypto (except clients _hate_ that). – Donal Fellows May 18 '11 at 10:40
  • 2
    @Steve314 my point is anything on the client is compromised by default. You can hash and hash and hash, if it is being done on the client and being passed back and forth to the server in the `clear` it is just mathematical masturbation at that point. I had to fix a system I inherited, that was designed the exact way you and the OP describe, it was constantly being hacked by teenagers with Wireshark. We only locked it down when we put in `REAL` encryption and encrypted and signed all the payloads to and from the server, the account manipulation stopped and never happened again after that. –  May 18 '11 at 16:27
  • 5
    It sounds like your plan for protecting yourself against rogue sites is to ask the rogue sites to set up better security. ? – pc1oad1etter Mar 09 '12 at 16:15
  • 3
    The best solution is (imo) a client side password manager. That way, you can generate a random string of characters as your password and you're not relying on the server to 'protect' you. – Dean Harding May 17 '11 at 22:20
  • I was also worried about this, so what I do is use a prefix + base strong password for every website. somecoolsite.com? scsSTR0ng!p@ss it is. the approach in the XKCD comic would be thwarted. I suppose if many databases were compromised one could look for the invariant and then try to guess the prefix for another website. then again that's one clever bot. – trianta2 Oct 09 '15 at 21:12
  • 1
    @JarrodRoberson You completely missed the point. The reason you hash the password is to protect the originally typed password, basically the same thing a password manager does for you. Obviously the hashed password should *never* be sent to the server "in the `clear`"! Anyway, also don't forget the hash should be slow (SHA-256 of a password may be brute-forced in hours or days). To use proper terminology: it is recommended to apply key stretching to a passphrase before sending it to server. – Yeti Sep 05 '18 at 11:37
  • I think this bear repeating *a hashed password sent in the clear is no better than a password sent in the clear if the server is just comparing hashes, man in the middle attacks love this kind of "security"* every *"argument"* that thinks sending a hash in plain text instead of the password is some way *more secure* than just sending the password have disqualified their opinion with that statement as there is no difference because the hash is now the password and it is known in the clear. –  Sep 07 '18 at 18:16
  • 1
    @JarrodRoberson Yes, you are completely right. But it does not invalidate anything I've said. Without HTTPS there is no security at all, and without hashing server-side the password is stored in plain text. However, it is still recommended to ADDITIONALLY use key stretching (slow hash) client-side to protect users without password managers against e.g. hackers or system administrators who may intercept/access database who could harvest user passwords. And it may not have happened to your organization YET, but [have i been pwned](haveibeenpwned.com) demonstrates it still happens way too often! – Yeti Sep 07 '18 at 18:31
  • @JarrodRoberson: as multiple people have told you and as was indicated by the xkcd reference you deleted-this is not to secure the password from a MITM attack, this is to secure the password from the SERVER. This allows the same password to be reused safely, because the SERVER never knows your actual password. If the server doesn’t know your password then it doesn’t matter if the server is evil or simply breached - your password would be secure from being used elsewhere because it is unknown.It was never stored ANYWHERE.It doesn’t exist except in your mind and your browsers temporary memeory. – jmoreno Sep 08 '18 at 12:12
  • @jmoreno - you and others do not comprehend that it does not do what you are saying it does either ... –  Sep 09 '18 at 17:04
  • @JarrodRoberson: I say it prevents the server from knowing the users password, how is the users password exposed to the server? – jmoreno Sep 09 '18 at 17:36
  • 1
    Possibly duplicate of https://security.stackexchange.com/q/23006 – zypA13510 Sep 19 '18 at 01:58

8 Answers8

48

Why isn't it used? Because it's a lot of extra work for zero gain. Such a system would not be more secure. It might even be less secure because it gives the false impression of being more secure, leading users to adopt less secure practices (like password reuse, dictionary passwords, etc).

Rein Henrichs
  • 13,112
  • 42
  • 66
  • 3
    This is the best answer so far. –  May 18 '11 at 01:17
  • 1
    It's like Blu-Ray and DVD encryption. It doesn't even require a Key to unlock. The only "protection" it provided was that when DVDs first came out it cost more to buy a disc to copy it to than to buy a full copy of the movie. Of course now you can buy a dvd for a dollar and even more is the fact that the keys are public knowledge now. Same is happening with Blu-Ray – Michael Brown May 18 '11 at 04:07
  • 2
    I think hashing a password client-side does add security. If I'm listening in, I can only see your hash, not your password. If the server sends a challenge (as it should) the hash is not even reusable. – Andomar Jun 14 '12 at 09:13
  • 2
    I think x4u's approach may very well be appropriate for some applications where security requirements are somewhere between transmitting passwords on the wire and using certificates. I think some of the nay sayers are overlooking that the hashing of the password before it goes on the wire is done *in addition to* the standard server side credential handling. So the question is this: Does x4u's proposal improve security in the transmission-of-password-on-the-wire-scenario or not. I say it does. The key to realizing this lies in the usage of per-password salts. – LOAS Jul 23 '13 at 09:19
  • 6
    The correct way to prevent MITM attacks is end-to-end encryption. TLS (https) exists: use it. Don't invent your own crypto schemes. – Rein Henrichs Jul 24 '13 at 17:48
  • 1
    *Because it's a lot of extra work for zero gain*. This is incorrect. Hashing password on client side is extremely useful for offline web apps since users don't need to wait for server response to be authenticated. In addition, this *server relief* approach can help reduce DoS opportunities. – Lewis Apr 26 '15 at 07:55
  • Doing client side hashing by itself won't change much (it helps with replay attacks apparently). Doing client side hashing in addition to TLS is where it might be useful, it prevents you having the responsibility of holding the user's real password ever in your server environment (memory, storage, IO). – CMCDragonkai Sep 07 '15 at 10:35
14

In theory this doesn't give any extra security, but in practice this can be used to protect against "rogue sites" that don't hash your password in the server.

How exactly does this protect you? It sounds like all you want to do is hash the hashed password which is sort of pointless. Because the hashed password would then become the password.

There are many sites on the Internet that require login information, and the only way to protect against password reusing is the "promise" that the passwords are hashed on the server, which is not always true.

How about not using the same password for more then one site. The reason websites hash the password in theory is to prevent access to your account if THEY are compromised. Using the same password for multiple websites is just stupid.

If you did use javascript, all the "hacker" would have to do is, use the same method on the hashed-hashed-passwords. Once you have the hashed information its just time it takes to compute the password->same hash in the database that is a factor preventing access to an account.

Channel72
  • 2,475
  • 5
  • 27
  • 28
Ramhound
  • 871
  • 8
  • 12
  • 1
    If your browser always hashes it the same way, then yes your hash can be used as a password everywhere else. But what if browsers assigned a salt based on the site (maybe the domain?) before hashing and sending that to the site? I think it's an interesting idea. – Tesserex May 17 '11 at 14:43
  • What about salts? – StuperUser May 17 '11 at 14:44
  • 2
    if it is on the client it is compromised, any salt on the client is in plain view, this is an illogical question. if you don't understand @Ramhound's answer you should not be writing code that needs to be secure, and start reading up on security and cryptography from the beginning. –  May 17 '11 at 16:52
  • 3
    When you are quoting the original poster, please format the text as such (select the text and use the quote icon just above the editor) – Marjan Venema May 17 '11 at 18:19
  • @Jarrod: It can actually be implemented in a secure way, see my answer for one possible approach. So you are obviously right, security problems and solutions are not easy to comprehend for quite a few people as can be seen on this question. I got 3 down votes for a working and secure suggestion and this answer is voted top although it is simply wrong. ;) – x4u May 17 '11 at 20:27
  • @x4u your solutions isn't secure either, it is complex and convoluted, but it isn't secure then security through obscurity. You will just get more down votes and hope someone takes the time to explain why your "solution" isn't a good one. –  May 17 '11 at 20:49
  • 1
    Jarrod, please follow your own advice and get a bit informed yourself before you make ridiculous claims. A man in the middle attack is useless against secure hash functions with reasonable salt length. And my suggestion is in no way 'security by obscurity', it is actually safe based on what is currently known and accepted by the *experts* in this field and it is used the same way in many protocols. It is not my invention, I just applied a well understood procedure to a website login. Your false assumptions don't gain any substance by the fact that they are obviously shared by many others too. – x4u May 17 '11 at 21:06
  • @Jarrod - The whole point of a salted hash is that it's not possible to undo the hash. A hash doesn't even contain all the information from the original password. If the hashing is done client-side, neither the server nor a man-in-the-middle can see the unhashed password, so neither can use it on other sites. Knowledge of the salt doesn't change that. –  May 17 '11 at 22:36
  • 3
    If the salt is known by the client and it is sent in the clear from a server, anything in the middle knows it as well. Never said, I needed to undo the hash, if you know the salt on the client, then isn't secure. –  May 18 '11 at 01:11
  • What on earth is the point of this when you can just choose random, high-entropy passwords? – Rein Henrichs May 18 '11 at 03:51
  • 1
    @Ramhound: I am not your personal editor, mate. And I did not complain, I gave you a suggestion. – Marjan Venema Mar 05 '12 at 20:22
  • 1
    Wow I am quite surprised at all of the comments and answers. A SALT isn't meant to be secret. It being known is actually part of its implementation. The SALT is used to break rainbow tables. While hashes are one way there exists precalculated databases of word and their hashed values. Without a SALT you just look up the hash in this database to return a know word/password. The SALT breaks the rainbow table. It is not reasonable to create new rainbow tables for each SALT. This is how it becomes secure. The time it takes to find a password to generate that hash is unrealistically achievable. – Andrew T Finnell Sep 20 '14 at 22:10
11

Because it would add little to no value. The reason hashing is that if your database gets hacked, the hacker would not have a list of valid password, just hashes. Therefore they could not impersonate any user. Your system has no knowledge of the password.

Secure comes from SSL certificates plus some form of authentication. I want my users to supply a password so I can calculate the hash from it.

Also, the hashing algorithum would be on the server in a more secure area. Putting it on the client, it's pretty easy to get the source code for Javascript, even if its hidden referenced scripts files.

Jon Raynor
  • 10,905
  • 29
  • 47
  • 3
    This is the best answer. You should encrypt at the transport layer. Without doing that, the rest is not secure. Yes, you could write an encryption function... but that function would be visible to the (malicious) end users. Use SSL. – pc1oad1etter Mar 09 '12 at 16:14
  • The security of a hashing algorithm shouldn't be dependent on whether it's secret. Hashing algorithms for security should be one-way functions: even if you have the code, it's hard to undo it. On the contrary, you should use a well-known hash library designed just for passwords. If it's not well-known, it's almost certainly buggy or mispurposed. – leewz Nov 06 '18 at 17:07
10

most replies here seem to completely miss the point of client-side password hashing.

the point is not to secure access to the server that you are logging into, since intercepting a hash is no more secure than intercepting a plain text password.

the point is really to secure the user's password, which is usually far more valuable than individual site login access since most users will reuse their password for multiple sites (they shouldn't but the reality is that they do so it should not be waved off).

ssl is great for protecting against mitm attacks, but if a login application is compromised on the server, ssl won't protect your users. if someone has maliciously gained access to a web server, they will likely be able to intercept passwords in plain text because in most cases passwords are only hashed by a script on the server. then the attacker can try those passwords on other (usually more valuable) sites using similar usernames.

security is defense in depth, and client-side hashing simply adds another layer. remember that while protecting access to your own site is important, protecting the secrecy of the passwords of your users is far more important because of password reuse on other sites.

crutchy
  • 133
  • 1
  • 2
  • it's probably more of a comment than an answer (apologies for not figuring out how to add to the accepted answer comment thread), and even though my point is shared in the accepted answer, it apparently wasn't clear enough since replies to it seem to brush it off still. thanks for the feedback – crutchy Aug 01 '16 at 12:34
  • @Frank the accepted answer borders on being too long to bother reading. it goes into way too much detail of how this can be implemented and skims over benefits towards the end. Having a TL;DR in a different answer is beneficial. – Jules Aug 01 '16 at 19:55
  • 2
    @Jules: That's why editing exists. – Robert Harvey Aug 02 '16 at 15:20
  • A string of numeric character (hash) that gets stored in the clear is not better than a string of alpha-numeric characters that gets stored in the clear. What part of this do people not want to acknowledge. This is all just obfuscation and misdirection and overly complex mathematical masturbation that is in no way "secure". –  Sep 07 '18 at 18:43
  • 1
    @JarrodRoberson I think you are confusing _no more secure_ with _insecure_? If MITM happens, access to the site is already given up, isn't it? Unless you use client-certificate instead of password, which would be _overly complex_ for ordinary users. The way I see it, client-side hashing prevents the same password being compromised on other sites, assuming each hashing algorithm is unique. It may not be more secure, but it's not less secure in any way either? So why do you push so hard on this? I came across this from meta, and this is the best answer I see so far. – zypA13510 Sep 19 '18 at 01:55
7

The solution is simpler than that. Client certificates. I create a client certificate on my machine. When I register with a website, we do a handshake using my client certificate and the server's certificate.

No passwords are exchanged and even if someone hacks the database all they'll have is the public key of my client certificate (which should be salted and encrypted by the server for an added level of security).

The client certificate can be stored on a smart card (and uploaded to a secure online vault using a master password).

The beauty of it all is it removes the concept of phishing away...you're never entering a password into a website, you're just handshaking with that website. All they get is your public key which is useless without a private key. The only susceptibility is finding a collision during a handshake and that would only work one time on a single website.

Microsoft tried to provide something like this in Windows with Cardspace and later submitted it as an open standard. OAuth is somewhat similar but it relies on an intermediated "issuing party". InfoCards on the other hand could be self issued. That's the real solution to the password problem...removing passwords altogether.

OAuth is a step in the right direction though.

Michael Brown
  • 21,684
  • 3
  • 46
  • 83
  • 5
    While client certificates are a reasonable approach for some use cases, they are not something that can be added easily to a website login. They require a great deal of cooperation from the users and depend on how secure the users private key is. The usage of a private key can be either secure or convenient but not both at the same time. – x4u May 17 '11 at 20:13
2

It is definitely possible, and actually you do not need to wait for a website.

Have a look at SuperGenPass. It is a bookmarklet.

It simply recognizes passwords fields, concatenates what you type with the website domain, hash it, mangles it somewhat so as to get only "admitted" characters in the password, and only then is your hashed-password sent on the wire.

By using the site domain in the process, you thus get a unique password per site, even if you always reuse the same password.

It is not extremely secure (base64-MD5), but you perfectly distribute a sha-2 based implementation if you wished.

The only downside is if the domain change, in which case you'll need to ask the website to reset your password because you'll be unable to recover it by yourself... it does not happen often though, so I consider it an acceptable trade-off.

Matthieu M.
  • 14,567
  • 4
  • 44
  • 65
  • This is what I was thinking when I read the question; it's practically useless for sites to do their own client-side hashing, but a browser extension that does it (using some salt based on the domain) would effectively nullify the risks associated with password reuse. Of course, the fun part comes when you try to log in from another machine... – Aaronaught May 17 '11 at 23:32
  • 3
    this isn't anymore secure than any other scheme that passs the password in the clear. It makes the password unique but it still **isn't encrypted**, but if I have a server in the middle, I can just grab the complicated but still clear password and use it as much as I want, it isn't changing. A hash isn't some magic bullet, it isn't even encryption, they are called cryptographic hashes, but that doesn't mean they are encryption. Doesn't matter if my password is `password` and or an SHA-256 of `password` with some salt that is know to the client, a man in the middle attach can capture it. –  May 18 '11 at 01:17
  • @Jarrod Roberson: you can use the password of course, but you cannot reuse it for another of my accounts, which is the point. Therefore, if one of the website I connect on got his password base stolen, and they stored them in the clear, then my other accounts are safe. – Matthieu M. May 18 '11 at 07:00
  • @Aaronaught: that is where it shines actually. Since the password sent is derived purely from the website domain you log on and a master password of your choice, you can login from any computer (and browser) as long as you have the bookmarklet. This is why it's somewhat more comfortable than a certificate. – Matthieu M. May 18 '11 at 07:02
  • @Matthieu I don't need client side hashing nor some plugin into my browser to do what you are talking about, **all I need is to not be a dummy** and **not** use the same password of multiple logins, client side hashing doesn't factor into anything in your scenario. –  May 18 '11 at 16:22
  • @Jarrod: I don't want to seem mean... but go ahead and remember 35 different passwords if it amuses you, I've got better things to employ my memory to. – Matthieu M. May 18 '11 at 17:23
  • @Matthieu it isn't about memorizing passwords, the question was about **client side hashing as a security measure** to try and compensate for servers that store passwords un-encrypted, which your answer doesn't even deal with directly. –  May 18 '11 at 17:59
  • 7
    @Jarrod: This isn't a security measure for the *site*, it's a security measure for the *user*. If everybody used a scheme like this, password reuse would be a non-issue. A MITM scheme could use the client-hashed password to gain access to *that* site, but *only* that site. That's where the improvement lies. Ordinarily you'd expect to be able to gain access to a *lot* of accounts by simply cracking one password, because that password is likely to be reused; in this case, the cracked password is practically guaranteed to only be valid for the site or database it was found in. – Aaronaught May 18 '11 at 22:29
0

I like X4u's answer, but in my opinion something like it should be integrated into the browser/the html specification - as at the moment it's only half the answer.

Here's a problem I have as a user - I have no idea whether my password is going to be hashed at the other end when stored in the database. The lines between me and the server may well be encrypted but I have no idea what happens to my password once it reaches the destination - it maybe stored as plain text. The database admin guy may end up selling the database and before you know it the whole world knows your password.

Most users reuse passwords. Non technical people because they don't know any better. Technical people because once you get to the 15th password or so most people don't stand a chance of remembering them unless they write them down (Which we all know is also a bad idea).

If Chrome or IE or what ever it was I am using could tell me that a password box is instantly going to be client side hashed using a server generated salt and effectively sandbox the password itself - then I would know that as a user I could reuse a password with less risk. I'd still want the encrypted channels as well as I don't want any eaves dropping going on during transmission.

The user needs to know that their password is not even available to be sent to the server - only the hash. At present even using X4U's solution they have no way of knowing this is the case because you don't know if that technology is in use.

Chris Nevill
  • 320
  • 1
  • 10
  • 1
    it is integrated into the browser look up digest authentication and you'll see the back-and-forth steps taken in http to get a password hashed, with extra info, and verified on the server. – gbjbaanb Aug 01 '16 at 11:28
-1

I think it's a good method to use when building something like a framework, CMS, forum software, etc., where you don't control the servers that it might be installed on. That is, YES, you should always recommend use of SSL for logins and logged-in activity, but some sites using your framework/cms won't have it, so they could still benefit from this.

As others have pointed out, the benefit here is NOT that a MITM attack couldn't allow someone else to log into this particular site as you, but rather that that attacker wouldn't then be able to use the same username/password combo to log into possibly dozens of other sites you might have accounts on.

Such a scheme should salt with either a random salt, or some combo of site-specific and username-specific salts, so that someone who gains the password can neither use it for the same username on other sites (even sites using the identical hashing scheme), nor against other users of the site site who might have the same password.

Others have suggested that users should create unique passwords for every single site they use, or use password managers. While this is sound advice in theory, we all know this is folly to rely on in the real world. The percentage of users who do either of these things is small and I doubt that will change any time soon.

So a javascript password hasher is kind of the least that a framework/cms developer can do to limit the damage of someone intercepting passwords in transit (which is easy over wifi networks these days) if both the site owner and the end users are being negligent about security (which they likely are).