views:

104

answers:

3

I'm in the designing stages of a custom tcp/ip protocol for mobile client-server communication. When not required (data is not sensitive), I'd like to avoid using SSL for overhead reasons (both in handshake latency and conserving cycles).

My question is, what is the best practices way of transmitting authentication information over an unencrypted connection?

Currently, I'm liking SRP or J-PAKE (they generate secure session tokens, are hash/salt friendly, and allow kicking into TLS when necessary), which I believe are both implemented in OpenSSL. However, I am a bit wary since I don't see many people using these algorithms for this purpose. Would also appreciate pointers to any materials discussing this topic in general, since I had trouble finding any.

Edit

Perhaps the question should have been: is there a best practices approach for secure passwords over unencrypted tcp/ip? If not, what are the reasons for selecting a particular method over others? (The Rooks answer is closest in spirit to this question so far, even if it does violate the letter).

Edit, part deux

I'm primarily interested in the case of client-server authentication, where there is an expectation that both parties have a shared secret (password) a priori.

+5  A: 

You should have a look at "Diffie-Hellman key exchange":

Diffie–Hellman key exchange (D–H) is a cryptographic protocol that allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel. This key can then be used to encrypt subsequent communications using a symmetric key cipher.

Once you have exchanged a key, you can encrypt your password with this key and transmit it over the insecure protocol.

tangens
+1 a Dh key exchange does solve his problem. However DH key exchanges do not protect against active MITM attacks, only passive.
Rook
D-H seems inferior to SRP or J-PAKE for this purpose, since the latter two verify the password as a by-product but the former requires extra work to encrypt/decrypt the password after establishing a key. Am I missing some subtlety here?
academicRobot
+2  A: 

You could use a challenge-response algorithm. The algorithm goes like this:

  • The server sends a random string to the client.
  • The client combines this string with the password (by combining, you can xor them or just append them).
  • The client calculates a hash (for example, SHA1) of the result, and sends it to the server.
  • The server calculates the same hash using this random number and the real password.
  • The server compares the two hashes.

Since you shouldn't store a password in plain text, but as a hash instead, the client should calculate this hash at the very beginning.

There are possibly several libraries implementing this, so you probably don't need to code it yourself.

petersohn
The security of this simple CR algorithm is much weaker than Diffie-Helman key exchange, because here the knowledge of the hashed password is enough to authenticate a client against the server!
tangens
I know. CR is a password-based symmetric key authentication algorithm, while DH (and RSA) are asymmetric key algorithms, where the client has its own private key. What we use depends on what you need. Most websites still use password authentication through an encrypted tunnel, instead of some more elaborate method.
petersohn
+3  A: 

I still think that SSL is by far your best choice, after all why reinvent the wheal when so much can go wrong? You don't have to buy an expensive certificate if your have a list of "good" and "bad" (compromised) certificates. openSSL is completely free, and i don't see a good reason not to use it.

Some things you might not know: ssl handshakes can be resumed.

Also you can use SSL/TLS over UDP to reduce overhead its called DTLS.

Rook
Could you please elaborate a bit on this: "You don't have to buy an expensive certificate if your have a list of "good" and "bad" (compromised) certificates".Thanks for pointing out reusing SSL handshakes, I wasn't aware of this.Unfortunately, UDP isn't an option on some mobile platforms, but I like this idea in principle.
academicRobot
@academicRobot a certificate is just a number, often people pay a Certificate Authority to sign it but you don't have to. You care make a self signed certificate (http://www.akadia.com/services/ssh_test_certificate.html) for free. You can check that they are valid against a database. If you are using Apache then you should use these environment variables (http://httpd.apache.org/docs/2.0/mod/mod_ssl.html).
Rook
Yes, I'm familiar with certs and self-signed certs (testing and personal use). I'm stuck on the "good" and "bad" part (I should have been more specific). Are you saying the client should keep a list of certs that it trusts? How does the client determine when they've been compromised?
academicRobot
@academicRobot using a SQL database to keep track of good and bad certs works well for a simple server<->clients scenario. If you need clientsto authenticate each other then you need a full PKI (http://www.openca.org/). If you just have a ton of clients that need to authenticate to one server, then clients don't need their own certificate, you could hardcode your public key in the Client and that could be used to verify the connection. If i didn't answer your question could you give more details?
Rook
@The Rook OK, that was my confusion. I am in fact only worried about simple client-server comms. I hadn't even considered the more general case; thanks for the food for thought.
academicRobot