5

I used client side password hashing in my register and login project.

Its purpose is to prevent passive adversaries/eavesdroppers from discovering users' plaintext passwords when HTTP requests are in transit.

But still an attacker can perform a brute-force attack against the hash; And i think most or at least many passwords will be discovered this way, because they are too weak to resist against powerful brute-force attacks.

So I recently thought of using asymmetric encryption.

Passwords will be encrypted with a public key on the client side (with randomized padding to make brute-force attacks impossible).

Is this a good idea?

Is it worth its costs?

Do u know about any problems regarding such a scheme?

Any related info is appreciated.

H M
  • 2,897
  • 6
  • 22
  • 21

2 Answers2

8

Firstly, I'm assuming that you're doing this to weaken man in the middle attacks (which really are the only problem when it comes to plaintext passwords over insecure HTTP)

Client side hashing has little to no benefit. An attacker, on picking up the hash will not need to brute force the hash. All your server needs is the hash, so the attacker can simply craft a POST request with the hash in it and send it over. One doesn't need the plaintext to get in to the system.

Regarding your solution:

If you're using the same public key for all clients, then the situation is effectively the same. As an attacker all I need to sniff is the ciphertext you send over, and I can impersonate you by sending the same ciphertext.

What if you gave different public keys to each client on each login? Then I could launch a man in the middle attack where I swap the server's public key with my own, decrypt the ciphertext you send (this getting your plaintext, even better), and encrypt it with the server's public key.

There has got to be a way for the client to know which public key is correct. For that you'd need some kind of trust system. Where clients know which public keys correspond to which server. But that will lead to millions of public keys being stored in browsers. So you'd need some sort of certificate chaining system. And I think you realize where I'm going with this ;-)

TL;DR: Use HTTPS, client side encryption without a trust system is not any more secure than no encryption at all.


If you're worried about shared passwords on other sites being detected after breaking the hash, then both hashing and public key encryption are fine (public key encryption is better due to rainbow tables). Note that these will only foil the plans of a passive attacker. If the attacker mounts an active MITM attack, then they can change the JS code that you send and remove the encryption bits entirely.

Manishearth
  • 8,237
  • 5
  • 34
  • 56
  • the reason i want to protect password is the same reason why we don't store plaintext password on the server side and use a hash instead. the benefit of that hash is for when the system is already compromised (at least to some extent); we want to limit the potential damages that can be done. e.g. plaintext passwords can be used to attack the other (not compromised) accounts of users. likewise, i want to limit the damage from passive adversaries/eavesdroppers when the requests are in transit over insecure channels. i think not all attackers are or can be active (always). – H M Apr 28 '13 at 10:17
  • @HM: As an attacker, I can just modify the JS code you send over to not encrypt the password. That's not hard, and I'll be able to sniff the plaintext. – Manishearth Apr 28 '13 at 10:23
  • Anything you do on the client side can be spoofed. IIRC on a network if someone can read your communications, they can modify them as well (cf ARP spoofing et al) – Manishearth Apr 28 '13 at 10:25
  • please read my comment carefully. i said protection against passive attackers only. are all attackers always active and can they be? – H M Apr 28 '13 at 10:26
  • i am not discussing about whether HTTPS should be used instead of HTTP. u think what fraction of web that should be using https is really using it? do u really think that the only reason for this is ignorance? – H M Apr 28 '13 at 10:27
  • @HM: Not exactly sure, but AFAICT if you are able to _read_ packets meant for someone else, you can forge them as well. – Manishearth Apr 28 '13 at 10:35
  • @HM: I never said that not using HTTPS is bad. I'm saying that _additional_ levels of security can only be brought forth via HTTPS. – Manishearth Apr 28 '13 at 10:36
  • i think active attacks need more knowledge/skills, careful prior tests and planning, more risk of detection, more resources, tools, ... so seems not everyone can always perform active attacks effectively. – H M Apr 28 '13 at 10:38
  • @HM: Not exactly. Using Wireshark with filters it is easy to modify packets. It's not a complicated process. – Manishearth Apr 28 '13 at 10:40
  • i think of, maybe sometimes an http request is passing through an attacker controlled machine/route only once or rarely. don't seems to me that attacker is ready and functional for preforming active attacks against all such requests belonging to different web sites with different codes. i think there is even the possibility that the corresponding response be passed through a different route, so the attacker can't get the results. but plaintext passwords from any http request going to any web site can even be detected and collected automatically. – H M Apr 28 '13 at 10:52
  • 1
    @HM: See edit, I've updated to include this. However, if I were an attacker, I would inject a keylogger script in every page I attack that sends me data entered into a username/password field. And that would bypasss most client side encryption. – Manishearth Apr 28 '13 at 10:58
3

This is what I understand from your question.

  • You accept a password at the client side
  • You random pad the password.
  • You hash the password at the client.
  • You encrypt the hash using the public key of the server
  • You send the encrypted hash to the server
  • Server decrypts the hash using it's private key & compares it against it's stored hash to check the validity.

The problem here is a replay attack. Anyone who eavesdrops the encrypted hash can reuse it.

The solution to this can be

  1. Add the current time to the password at the client side. Then hash it. When the server decrypts what it gets - it first splits the package into password hash & time. Only if the time is within +- delta of the current time, it checks the password. This will disallow reusing the eavesdropped encrypted hash unless it's used very quickly.
  2. Take the above scheme and also add a ID number to the password + time string. And then hash etc. Server's responsibility is to make sure a particular ID number is not reused for a particular client on the same day. Client's responsibility is to make sure it doesn't reuse the same ID number on the same day. This will prevent a replay attack even if done very shortly after the event.

One very important component here is that the server's certificate (public key) has to be pre-installed on the client - it shouldn't be that the client gets the certificate by requesting it from the server.

user93353
  • 1,982
  • 3
  • 19
  • 33