Maenny
Maenny

Reputation: 139

Sending passwords to server in a secure way

I am currently working on a better login-routine for one of my websites and I wanted to adress securely transmitting login-Data to the server. There are several articles and posts concerning this topic, but they frequently have quite different opinions on how it has to be done.

Starting off with SSL, pretty everyone is on the same page here: You should use SSL, and I do. Then there are those who say: "That is enough, with SSL you can send username & PW as plaintext". I disagree. Other say that it should still be hashed. And I read several posts where I had the feeling that people were concerned about different aspects of a login routine and proposed mechanisms to only handle their security aspect.

So what I want to know, if the routine I have so far elaborated would be adequate, too much or too little. I will try to explain why I chose to implement a certain feature and which security aspect I try to cover:

  1. SSL:

The communication between server and client should always be https:// - nevertheless I read several articles warning that SSL is "no silver bullet", but it is a good start.

  1. Hash PW clientside (SHA3, ARGON2i, BCRYPT):

Many comments did reject hasing PW. Using a hash, comparing it to a HASHed PW in the database would simply change the PW from the userinput to the HASH - an attacker would still have access by simply getting hands on the HASH. I agree. BUT (this is what I meant that people read about different aspects of security) the ones claiming that it is better than sending plaintext because in that case ONLY your system, but not other systems with the same PW would be compromised (unless, of course they use also hashed PWs). So I would implement HASHing of the password before sending it via SSL.

  1. encrypting the HASH:

Let's assume SSL could not hide the data we send to the server and an attacker would read the HASHed PW. The only way that I could think of to adjust the security to this scenario, would be to encrypt (e.g. AES CBC) the client-side HASHed PW with a key that has been send beforehand by the server, and that has a short expiration period. The key would have to be generated randomly. Like that, the server can decrypt the data, and then compare the HASH with the one it its database.

To sum it up:

-> Clients wants to Login via SSL -> Server sends back a key -> Clientside hashing of the PW -> clientside encryption of teh HASH with the key and a random IV -> Server decrypts the data with the key (stored in $_SESSION, with an expiration timestamp) and compares the HASH with the HASH in his DB (if the expiration timestamp is still valid).

Would this be a good approach? Or is this too much? (Can there be too much security?) Or do you have any alternative solutions?

Upvotes: 1

Views: 462

Answers (3)

Narf
Narf

Reputation: 14752

Or is this too much? (Can there be too much security?)

You're talking about it like security is a liquid that must fill-up a container without overflowing it. That's not how it works and you're asking the wrong questions, which means you're trying to solve the wrong problem. It has nothing to do with the amount of measures that you pile up, but whether and how they address a specific problem.

If the problem is protecting data in transit, then the solution is TLS (SSL) - that's what it is specifically designed for, and anything that you can come up with would, in the very best case scenario, be a poor alternative to it. You can't outsmart the decades of research and practice that has gone into TLS.

That was already answered by Jay Blanchard though ... I want to point out the mistakes you've made, because otherwise it looks like one man's word vs. another (and you may listen, but other readers might not):

  1. SSL:

The communication between server and client should always be https:// - nevertheless I read several articles warning that SSL is "no silver bullet", but it is a good start.

It is both a silver bullet and not a silver bullet, depending on how you look at it.

When we talk about protecting data in transit, it is THE solution - a silver bullet in a way.

But that doesn't mean flaws won't be found in time, or that you just switch it On and say "I have TLS, I am secure!" - no, it still requires proper configuration, maintenance and adjustments over time. In that sense, it's not a silver bullet.
It also doesn't solve many other security issues, so when someone asks "How do I make my application secure?", of course you would say that it is not a silver bullet - many threats need to be separately addressed and there's no one-stop shop for them all.

  1. Hash PW clientside (SHA3, ARGON2i, BCRYPT):

Many comments did reject hasing PW. Using a hash, comparing it to a HASHed PW in the database would simply change the PW from the userinput to the HASH - an attacker would still have access by simply getting hands on the HASH. I agree. BUT (this is what I meant that people read about different aspects of security) the ones claiming that it is better than sending plaintext because in that case ONLY your system, but not other systems with the same PW would be compromised (unless, of course they use also hashed PWs). So I would implement HASHing of the password before sending it via SSL.

It's the exact opposite - when you hash the password on the client side, that only makes accounts on your site easier to compromise after a data breach.

Lookup the hash in the database - got the password right there, that's the part you figured out. But that hash is still the result of a certain user-provided string ... Nothing stops an attacker from applying the same techniques to break the hash in order to compromise accounts on other servers.

So, this doesn't in any way solve the problem, but you'll probably think that in the worst case it doesn't do anything bad ... Well, indirectly it does - you have to make a considerable effort, to implement something with a lot of potential for mistakes.
In the best case scenario, you're just wasting your time, but a minor mistake can be a major vulnerability.

Also, SHA-3 is a cryptographic primitive - it has many appliances, but mostly as a building block. You can't just put one round of it on a password and be happy with the resulting hash.
For a comparison, bcrypt uses Blowfish internally (as a primitive of the same kind as SHA-3), but you cannot equate Blowfish to bcrypt.

  1. encrypting the HASH:

Let's assume SSL could not hide the data we send to the server and an attacker would read the HASHed PW. The only way that I could think of to adjust the security to this scenario, would be to encrypt (e.g. AES CBC) the client-side HASHed PW with a key that has been send beforehand by the server, and that has a short expiration period. The key would have to be generated randomly. Like that, the server can decrypt the data, and then compare the HASH with the one it its database.

There are valid reasons to encrypt password hashes, but not for this purpose and certainly not on the client side.

You need a secure key-exchange protocol for this to even work. And guess how you do that? TLS.

There's literally nothing different between communicating an encryption key or a password over the wire. So, even if this was somehow a solution to protecting a password, how would you apply it again on the key itself? It makes no sense.

Upvotes: 5

deceze
deceze

Reputation: 522625

-> Clients wants to Login via SSL -> Server sends back a key -> Clientside hashing of the PW -> clientside encryption of teh HASH with the key and a random IV -> Server decrypts the data with the key (stored in $_SESSION, with an expiration timestamp) and compares the HASH with the HASH in his DB (if the expiration timestamp is still valid).

Why encrypt a hash? That implies that the hash isn't secure enough. OK, fine, let's go with that. So let's assume an attacker is able to read the hash, and that's the reason you want to protect it with an additional layer. If an attacker is in a position to read the hash, they're also in a position to read the key sent by the server to the client, and the Javascript which contains the encryption algorithm (assuming you're talking about an HTML scenario here). Now the attacker has everything to replicate and reverse the encryption, and in fact they are probably also in a position to alter the Javascript sent from the server to the client in the first place.

To protect against that happening, you'd need some wrapper that protects all the communication between the client and the server, like, oh, uhm, say… SSL.
Since SSL already protects the communication from 3rd party interference… what do you think you're adding with that additional song and dance exactly? I'll tell you: nothing.

Upvotes: 1

Jay Blanchard
Jay Blanchard

Reputation: 34426

SSL is just fine, I have no idea why you disagree. Client-side hashing still leaves the PW visible on the client-side as well as the hash, so nothing gained there.

The question comes down to, "what are you protecting?" My guess is that you're not guarding anything needing more security than banks, and probably way less than that.

You're spending a lot of time trying to re-invent the wheel here, rather than relying on tried and true methods. Stick with what is proven.

Upvotes: 2

Related Questions