The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Network Security Question

I have a client and server apps that need to communicate.  Passwords (and other data) get passed between them so it needs to be secure.  Right now the client and server are on the same box, but some day they'll be across the Internet from each other.

I _should_ use OpenSSL, but it's such a pain in the butt that I've done the following instead.  Please critique:

1. Client and server have a shared pass phrase setup at installation time
2. Using shared pass phrase one of them encrypts a session key and sends to the other. 
3. The other decrypts session key using shared pass phrase.
4. From this point on all traffic is encrypted with session key.

All encryption/decryption is being done with Crypto++ AES (didn't roll my own on that one).  In addition, the stream is compressed, which wouldn't help security in theory, but would probably help in practice (unless the NSA is after me!).

As I see it, the only real weakness is the initial shared key.  I like the shared key phrase because of simplicity (people using my app can just copy-paste the pass phrase to the new machine).  Each client-server pair would have it's own key phrase.

Is there a better way that is also simple (perhaps without creating public/private keys and having to manage all that)?
anon for this
Thursday, March 27, 2008
 
 
I am no expert on the subject but I seem to remember there is a Diffie-Hellman algorithm to solve the problem of the shared keys. I don't know if some proven/tested library has it (would not recommend writting your own unless really knowing how to testit).

http://en.wikipedia.org/wiki/Diffie-Hellman
EdNoWeb
Thursday, March 27, 2008
 
 
EdNoWeb
Thursday, March 27, 2008
 
 
Yes, you should be using SSL (whatever implementation). You may THINK that using SSL is a pain in the butt, but I guarantee that is LESS of a pain in the butt than rolling your own solution that isn't really secure (the solution you have mentioned doesn't sound very secure, since it seems to use a symetric key for the key exchange).

Rather than spending your time trying to come up with a good encryption/key exchange scheme (something this is very difficult to do and which you are probably not expert in) you could have spent the time learning how to use SSL correctly. Reinventing the wheel is one thing, reinventing the jet-engine is a mistake of an entirely different magnitude.
Jeffrey Dutky Send private email
Thursday, March 27, 2008
 
 
But SSL without the proper certs isn't any better -- man-in-the-middle is still possible.  So it means all participant (at least all servers) need to have a proper machine-specific cert, signed by a trusted authority.  I can't impose that from a business stand-point.

So secure key exchange is what is needed.  You're right: It is using a symetric key for key exchange, which is the weakness.  I'm looking very closely at the Diffie-Hellman algorithm and trying to see if I can find a good implementation of it (I will NOT try to implement an encryption algorithm.  Luckily Crypto++ has take care most/all of that).
anon for this
Thursday, March 27, 2008
 
 
>I guarantee that is LESS of a pain in the butt
>than rolling your own solution

The phrase "reinventing the flat tire" comes to mind.

Seriously, once people have to have a pass phrase, it gets to be as complicated as SSL anyway.  And SSL does work.

Unless you are working for a bank or something, I don't think man-in-the-middle is a serious worry.

But then, IANASE (I am not a security expert).
.
Thursday, March 27, 2008
 
 
Note that since you control both the client and the server apps, you won’t have to fork out for SSL certificates.  You can operate your own private certificate authority and distribute the root certificate with the apps.
Dave Send private email
Thursday, March 27, 2008
 
 
Really; use SSL.

As people have said; you get bugs fixed without having to do it yourself. You've got a hundred other people looking at the systems for flaws instead of just you.

And the next person to maintain the code can buy the o-really to understand it.


As Dave says -- just generate certificates from your own root. It's trivial and the aforementioned book will walk you through it. Usefully, they can double as your software licences, making it harder to forge activations.

Encryption is one of those things that it's just not worth doing on your own unless you're an absolute expert at it.
Katie Lucas
Friday, March 28, 2008
 
 
How about an encrypted tunnel for all the communication. Check out stunnel.
IT Guy
Friday, March 28, 2008
 
 
I'm heavily considering SSL (even ordered the OpenSSL book) after reading the posts above.  But I just realized that my scheme also authenticates the client to the server and vice versa -- they can't communicate unless they have the same matching pass phrase (which is a requirement to setup a shared session key). 

To get the same result with SSL I now have to use per-server and per-client certs.

Really, if I just switch to Diffie-Hellman to establish the initial key, the one weakness (static initial key for session key exchange) is resolved.

Sigh, I want to live in a world with only honest people...
anon for this
Friday, March 28, 2008
 
 
Need to think before I type....  Using Diffie-Hellman would lose the advantage of authenticating since the pass-phrase is no longer used.
anon for this
Friday, March 28, 2008
 
 
you might want to use stunnel.org's stunnel thing. it can be setup different ways, but it can provide what ends up being a proxy ssl connection between two end points.

you redirect your local traffic on a specific port to it (its service intercepts the tcp traffic on a port). it relays that traffic to a specific port on another server. that server redirects the traffic to the real server. or something like that.

-don
Don Dickinson Send private email
Friday, March 28, 2008
 
 
You can also use an SSH server at one end and a client at the other to provide port forwarding through the encrypted tunnel.  With SSH you have more control over the key infrastructure.

It is pretty common to use a dedicated SSH server as a secure gateway into a network of servers.  You can run the SSH server on the same box as the application service in many cases though.

SSH is normally thought of as part of your network architecture, much as firewalls or VPNs are.  SSL/TLS is more of an ad hoc point-to-point application solution with many small warts as already described, but more scalable in terms of potential user community population due to certificate-based trust and encryption keys.
So tired
Friday, March 28, 2008
 
 
"To get the same result with SSL I now have to use per-server and per-client certs."

Yes. OpenSSL has a flag for requesting the client certificate (but annoyingly not mandating it. You have to write that check yourself).
Katie Lucas
Monday, March 31, 2008
 
 
Or you can establish an SSL connection to the server and then used a shared secret to validate the client.

Still has the risks of a shared secret but you don't have to worry about an insecure communication channel when communicating the secret.
use ssl
Monday, March 31, 2008
 
 
There are basically three areas you want to cover in secured communication: communication encryption, server authentication, and client authentication.

SSL can be a pain in getting the certificates and setting them up.  You need both server and client side certificates to have mutual authentication.  It's a pain to update the client certificate.  When you have more than one client, managing the client certificates at the server side becomes a pain.

If you are using server side certificate, then you still have to implement an authentication scheme to authenticate clients.

There are two practical options:

Option 1
- SSL for communication encryption.
- Server-side certificate for server authentication
- Add user/password for client authentication (the client must provide the correct user/password for the server to trust it).

Option 2
- Encrypt the communication yourself.
- Server password to authenticate it to the client
- Add user/password for client authentication.

Option 1 is fairly well understood.  It's a matter of implementation complexity and the pain of dealing with SSL.

You are already half way down in option 2, and this is what I am going to address to complete the implementation.  Basically you can use any challenge and response mechanism for authentication and key-exchange algorithm for exchanging a session key, like Diffie-Hellman.

A basic challenge and response protocol is fairly easy and goes like this.

- The server maintains a list of userid and password-hash HCP  (strong one-way hash like MD5/SHA, the plain password is not stored).

- The server also maintains its plain server-password SP and password-hash HSP.

- The client has its userid and plain password, CP.

- The client has the server's password-hash, HSP, to verify the server.

Client initiates the connection,

1. Client generates a random number CR1.
2. Client sends CR1, timestamp1 to server.
4. Server computes SH1 = hash(HSP, CR1, timestamp1).
3. Server generates a random number SR1.
5. Server responds with SH1, SR1, timestamp2.
6. Client computes SH2 = hash(HSP, CR1, timestamp1)
7. Client checks SH1=SH2, thus the server is authenticated.
8. client computes CH1 = hash(hash(CP), CR2, timestamp2)
9. client sends userid, CH1
10. Server computes CH2 = hash(HCP, CR2, timestamp2), looking up HCP from userid.
11. Server checks CH1=CH2, thus the client is authenticated.

At this point both the client and server can trust each other.  The DH key-exchange can occur to create a shared session key.  The session key is used for subsequent communication encryption.

The basic idea of challenge and response is for one side to generate some random number and ask the other side to hash it with the shared secret.  Only the hashed value is sent back so the shared secret is never transmitted.  The original side does a hash and compared it to the returned hash value.

The random number makes the hash value unpredictable.  When both sides are authenticated, you defeat the man-in-the-middle attack.  Throwing in the timestamp defeats the replay attack.

The DH key-exchange can be done before or after the challenge and response authentication.  It's up to you.

See, it's quite simple, and you don't need SSH!
been there done that
Tuesday, April 01, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz