views:

469

answers:

5

I'm working on a project in which remote clients need to log in to a webserver. I'm not looking for examples in any particular language; just a general idea of the security concerns involved.

The basic question is:
How should user credentials be passed to a webserver for verification?

I'm picturing your typical website login. One field for username, and another for password. You type in both and click "Log In". What happens next?

I can imagine a few scenarios:

  1. Credentials are sent to the server as plain text. A server-side script creates a hash of the password and compares it to the stored hash for the user.
  2. Credentials are encrypted locally, and the result is sent to the server. The server decrypts the credentials and continues as in #1
  3. Something I haven't thought of yet? I'm new to this. Go easy on me!

Option #1 strikes me as weak because the credentials are sent over the internet in plain text.

I see option #2 as not much better than option #1. If someone intercepts the encrypted credentials, can they not just send those to the server another time, and still manage to log in?

Any insight is appreciated.

edit: the "Related" sidebar suggests this question, which mentions a client/server handshake with a salt added to the password. Is that the right way to go?

+4  A: 

Option 1 is by far the default. The plaintext weakness is usually overcome by enforcing SSL during the login so that the password is at least encrypted during transit.

Edit: I suggest you follow the accepted answer for that question.

Don't forget to require a nonce for your request. This will help protect you against replay attacks.

Edit the second: Wayne thoughtfully mentioned that you should salt your password before you hash. Here are some basic tips:

  1. It doesn't matter if your salt is a prefix, postfix, or infix
  2. Your salt should be large, random, and complex.
  3. Your salt should be unique per salted value. The salt itself doesn't need to be encrypted.
Randolpho
Does that technically fall under Option #2, then?
e.James
I suppose it depends on how you read it. I read Option 2 to mean the use of some sort of client-side javascript encryption then posting the encrypted password plaintext.
Randolpho
And thank you for the link to the nonce article. I've never heard of that before :)
e.James
Hmm, fair enough. I wasn't 100% clear on the distinction.
e.James
It's old skool, but I'd only recently learned of it myself. I managed to avoid the need for secure programming for the longest time...
Randolpho
Does using a nonce require that the server store the password in plain text? I don't see how it can compare hash(nonce + cnonce + password) to something unless it is also able to compute hash(nonce + cnonce + password)
e.James
Well, the nonce should be more for session synchronization. It shouldn't be part of the salt, but should be used to verify that the login request came from the login page.
Randolpho
That makes more sense. Thank you for your answer
e.James
+3  A: 

Why not SSL the communications? Being able to observe the conversation gives me insight into your app. Encrypt the entire communication, not just the credentials.

Edit: Always use salt for a locally stored hash. Windows continues to fail as far as brute forcing locally hashed passwords because they do not salt by default.

Wayne Hartman
Yes, I forgot to mention salting before hashing. +1 and time for an edit.
Randolpho
A: 

On the client side you only have a browser that can render HTML and submit forms. Who's gonna encrypt stuff?

Send login and password in plain text (SSL it if you have concerns). On the server side you can do whatever you want with it (preferrably hash and salt password before storing them in the database).

User
+1  A: 

The simplest answer is to get an SSL certificate for your server. There's really no reason to mess around with creating your own encryption techniques in this particular application. As you've noted, if the connection isn't encrypted, you leave yourself open to man-in-the-middle attacks, regardless of whether the client or the server is doing the password encryption. Encrypt the connection, and you don't have to worry about it.

Steve Goodman
A: 

You might also want to consider using multiple iterations of the hash algorithm, 1000 iterations will slow things down nicely and make rainbow tables that much harder to create

Patrick