views:

201

answers:

3

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: http://www.cryptopp.com/wiki/Diffie-Hellman

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

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?

+2  A: 

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.

Note if you use Diffie-Hellman you still need to authenticate the parameters sent, which you probably need to do with RSA.

The alternatives are:

  1. Use RSA to exchange an encrypted secret key that you then use to encrypt your data.
  2. Use Diffie-Hellman to exchange a secret key and then use RSA to sign values sent to authenticate the transaction.

If you do all this, then you have to also worry about whether exchanges have been replayed to make you reuse keys etc.

To be honest if you need to ask this question then you probably are not qualified to write a crypto protocol. They are extremely hard to get right and not for the faint hearted.

Suggest you use SSL/TLS for your exchange if you need to stream a lot of data. PGP/PKCS#7 if you just need to send a single message.

Dean Povey
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 Trager
Agree totally, particularly with the suggestion to use either SSL/TLS or PGP.
caf
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.
abc
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 Povey
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.
Accipitridae
@Accipitridade I am not sure where you got the sense I was saying that was wrong, or that is at all relevant to the question. Please explain!
Dean Povey
+2  A: 

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).

Larry Osterman
A: 

If you can help it, don't send passwords over the wire at all. Instead, use a scheme like SRP, which authenticates both parties with one password.

Paul Crowley