I was given advice that I am suspicious about so I'm looking for support here to go back and challenge the advice.

I was advised to use Diffie-Helman to get both sides to agree on a secret key, use the secret key to generate an AES key, and then use AES to encrypt/decrypt passwords that are being transmitted. Pretty much like the sample code here

When using this scheme, the length of the encrypted password is the same as the length of the unencrypted password. Should I be worried about this?

Before, I was using RSA, encrypting the passwords with the receiver's public key. This was resulting in an encrypted length of 256 no matter what the password length. Isn't that better?

I'm no expert on security, but why don't pad the password to a set length (i.e. to 256 chars) to obscure the output?
–
Emil VikströmJan 19 '10 at 13:32

1

@Emil - But maybe my act of padding with a non-random character gives a clue to attackers? I definitely don't want to make up anything. I want to be told what to do by somebody who knows what he's talking about.
–
Corey TragerJan 19 '10 at 13:35

Can you please post more info about your problem so we can work out what you need?
–
Dean PoveyJan 19 '10 at 13:39

You can just pad to whatever length with any data. It doesn't have to be random. As long as it's all encrypted. I think though that is the least of your worries. How are you authenticating the DH exchange? How are you handling replays?
–
Dean PoveyJan 19 '10 at 13:42

I copied your comment about padding to this answer, because the padding was the answer to my narrow question about length. But, definitely, I'm grateful to you for raising the issue of authenticating the DH exchange.
–
Corey TragerJan 19 '10 at 14:21

Agree totally, particularly with the suggestion to use either SSL/TLS or PGP.
–
cafJan 19 '10 at 23:05

This answer doesn't make sense. Why would any client want to send a password if it had the possibility to authenticate itself with an RSA signature? As caf proposes, just use SSL/TLS instead. If the client authenticates himself with a password, then he only needs to validate the server certs to make sure he doesn't send to password to the wrong place. There are no client certs, client public keys or signatures by the client necessary.
–
abcJan 22 '10 at 11:57

It wasn't clear from the question, but there are plenty of reasons to send the password. One is if you need it to access a third party service, or decrypt some data on the server. Yes you should almost never send a raw password (even if it is encrypted) for simple authentication, but that doesn't mean that there are legitimate reasons not to send one.
–
Dean PoveyJan 24 '10 at 2:34

Dean, if what you say is true, then almost everyone using SSL is doing it wrong. Im most cases the client does not have an RSA key and does not authenticate himself.
–
AccipitridaeJan 27 '10 at 9:57

First off: Don't invent your own authentication protocol. Period. If you do, you WILL get it wrong even if you're using strong encryption. There are a number of existing well documented authentication protocols that have been vetted by cryptographers and thus are thought to be secure. Don't be tempted to "simplify" them, they've already been simplified.

Second: IMHO you should never send passwords on the wire for authentication (I'm not aware of any authentication protocol which does, including the hideously insecure NTLMv1 protocol)[1].

If you're dead set on going down the "roll my own authentication scheme" path, here's how I'd make the scheme you described above more secure (Caveat: I'm not a cryptographer - I believe that there are serious weaknesses in what I'm describing here):

Instead of sending the password directly, send a one-way-function (also known as a OWF, often implemented as a cryptographic hash like SHA256 or stronger) of the password.

In other words, have the server send the client a salt value, add the salt to the password, compute the OWF of the password+salt value and send the OWF result to the server. On the server, add the salt to the password and also perform the OWF calculation. If the results are the same, the password is valid, if they're not it's invalid.

And finally have whatever you do reviewed by a real cryptographer. They will find problems in your implementation and you're going to have to fix them. They're likely to suggest that you abandon your effort in favor of an existing published protocol.

[1] AFAIK, the only time you should send the password on the wire is when you're changing the password and even then, you should pad the length to a multiple of the block size (include the length in the cybertext so that when you decrypt it you can distinguish between the password and the padding).

Don't send the salt value to the client. The client should just return the hashed password. The server should store the salt and the password+salt hash. The server should add the client-hashed password to the salt value, and hash it, then compare the result to the database. The hashing and the salt is meant to hinder dictionary attacks against the database, not to secure anything on the wire (after all, a man-in-the-middle would likely see the salt going to the client).
–
McGuireV10May 16 '12 at 20:43