Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm currently developing a project for highly sensitive data which needs to be transfered over a very questionable network. While I'm not really happy about that at all, it's probably unavoidable anyway. The good news however is that the participating users are very limited, which would make it possible to use the Username/Password to actually encrypt the first packages that are sent. So here is what I'm thinking:

  1. The Client sends Username/Password-Hash encrypted with a key generated by a combination of the two using a bijective function.
  2. The Server trys to encrypt this using every single Username/Password-Hash combination found within the database, if successful

    2.1 a private Key is generated which is valid for the session only and will only be used once.

    2.2 The private Key is send to the client using the same Username/Password-Hash generated Key.

    if not successful

    2.3 NO LOGIN is send to the client using no encryption.

Well my question here is:

Will this method compromise the encryption in any way? Or am I completely missguided?

Using a public key is not really an option, since the key could be attained by reverse-engeneering/listening in on the first package where the public key is exchanged/...

share|improve this question

migrated from stackoverflow.com Jan 8 '13 at 21:23

This question came from our site for professional and enthusiast programmers.

    
If you need secure key exchenge why not use Diffie-Helman algorithm ? –  fatfredyy Jan 8 '13 at 14:37

3 Answers 3

up vote 0 down vote accepted

Using a public key is always an option. Public-key cryptography was designed to do exactly what you are trying to do; exchange sensitive information over an untrusted network (the Internet) without casual observers being able to sniff it.

Get your server signed with a certificate. If you don't need global trust (for instance, if you can manually "introduce" each client to the server inside a trusted network the first time, before attempting to connect over the untrusted one), you can generate a "self-signed" certificate for free, but if you want independent verification that you are who you say you are, go through a global CA which will sign your certificate, providing verifiable third-party confirmation of your server's identity (for a price of course, typically very reasonable).

Once you have this certificate, simply force all traffic connecting to your server to do so via HTTPS. The client will request the certificate (anybody can; it's public information), verify that the certificate matches the one they expect from you (or that the trust chain is valid all the way up to a "trusted root"), and then use the public key in the certificate to encrypt a message containing information about the symmetric algorithm they want to use. If you accept, you initialize that encryption scheme and send the acknowledgement back encrypted with their key; if not, you send a plaintext rejection and they try again.

This is the "SSL handshake", and it has been used for a very long time with very few successful attacks against it (usually leveraging a vulnerability in the hashing algorithm to generate fake certificates for phishing sites; just use an SHA-2 algorithm and you'll be fine). Once the symmetric encryption channel has been established, no matter how Wild Wild West the network is, data sent between client and server will be encrypted so nobody else can read it. Then, they can send you the user's credentials to log in and establish the "application session" over the secure network session.

share|improve this answer

Why aren't you using SSL? No, really.

Generate a self-signed certificate that you keep private. Then either use that certificate for your server or (better yet) use it to sign server-specific certificate. Ship the self-signed certificate (but not the private key, obviously) with whatever software you're intending to use.

Then when you initiate your SSL connection to the server, use the shipped certificate as your only trusted CA -- that is, don't accept connections signed by any other CA.

At this point, you're guaranteed to be communicating directly with your trusted server over a secured channel. No man-in-the-middle is possible because you only trust connections secured with your server key.

Now, authenticate the client using any mechanism you want. Since you're certain that eavesdropping or tampering or replaying isn't possible across the secured connection, you don't really have to do anything special.

share|improve this answer

I wouldn't recommend your scheme. It seems inefficient (having to create keys out of every username/password combination, just to find the origin), and unsafe, with the server generating private keys that get sent to clients. It's also vulnerable to replay attacks, since you're not protecting the underlying channel, though without seeing the rest of the details, it's unclear what that gets an attacker.

Why not just use SSL? It's meant for protecting sensitive information over insecure networks, is universally supported, and is likely to be safer than anything you implement.

If you need to store this data encrypted after the transfer, using a traditional public key scheme is certainly an option. There's no risk of someone snooping a public key, since they are meant to be public. As long as each parties public key is signed, either by eachother, or by some mutually trusted third party, then there's no risk of a man-in-the-middle attack.

tldr: Use SSL. If you need to store data after the transfer, use PGP.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.