0

I'm building an authentication server in python and was wondering about how I could secure a connection totally between two peers totally? I cannot see how in any way a malicious user wouldn't be able to copy packets and simply analyze them if he understands what comes in which order.

Admitting a client server schema. Client asks for an Account. Even though SRP, packets can be copied and sent later on to allow login.

Then now, if I add public - private key encryption, how do I send the public key to each other without passing them in an un-encrypted channel?

Sorry if my questions remains noobish or looks like I haven't minded about the question but I really have a hard time figuring out how I can build up an authentication process without having several security holes.

atk
  • 9,244
  • 3
  • 32
  • 32
cp151
  • 189
  • 2
  • 17
  • 5
    probably more apt for http://security.stackexchange.com – lazy functor Aug 05 '13 at 18:35
  • Have the public key exchanged between the two parties defined ahead of time and input to their clients. This is the only way - but even them a hijacked PC can have it's RAM hijacked etc. The simple answer: you can't. The more complicated answer: prevent sending sensitive over the network and have the users use other means to transmit the info. – Vaughan Hilts Aug 05 '13 at 18:36
  • 2
    The problem with constant surveillance has been considered before :p See [Diffie-Hellman](http://en.wikipedia.org/wiki/Diffie–Hellman_key_exchange) for example (not recommending it). The point is that there are safe ways to exchange keys on an insecure channel. – keyser Aug 05 '13 at 18:38
  • 1
    If you own both nodes, then you can simply give both secret keys and everything is always encrypted. If the nodes are dynamically allocated, that won't work, obviously. – Alexis Wilke Aug 05 '13 at 18:45
  • Somewhat pedantic, but the only way to "secure a connection totally" is to make sure the connection does not and can never exist. That's not real useful, though, so the focus tends to be "reasonable security" instead of "total security". One of the tenets of public-key encryption is that compromising the public key is not catastrophic - in fact the public key is usually, well, public... – twalberg Aug 05 '13 at 19:17

2 Answers2

3

You could use some sort of Transport Layer Security, simply a TLS/SSL wrapping for any network socket.

All the documentation here.

Simple client-side SSL encryption as demonstrated here:

import socket, ssl, pprint

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# require a certificate from the server
ssl_sock = ssl.wrap_socket(s,
                           ca_certs="/etc/ca_certs_file",
                           cert_reqs=ssl.CERT_REQUIRED)

ssl_sock.connect(('www.verisign.com', 443))

print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())

# Set a simple HTTP request -- use httplib in actual code.
ssl_sock.write("""GET / HTTP/1.0\r
Host: www.verisign.com\r\n\r\n""")

# Read a chunk of data.  Will not necessarily
# read all the data returned by the server.
data = ssl_sock.read()

# note that closing the SSLSocket will also close the underlying socket
ssl_sock.close()

More examples here.

Also, make sure to use the latest version of the algorithms to avoid cryptographic insecurities.

You might want to take a look at these questions:

Community
  • 1
  • 1
  • Oh thank you ! After this socket channel is putted up is it safe to use it to send public keys ? Other than that, any trouble with select ? – cp151 Aug 05 '13 at 19:38
  • 1
    It should be safe, I guess. But remember enough security is never enough. There is always someone or something that can always crack it. –  Aug 05 '13 at 19:43
2

What you are asking about is part of what's commonly called "key management." If you google the term, you'll find lots of interesting reading. You may well discover that there are other parts of key management that your solution needs to address, like revocation and rotation.

In the particular part of key management that you're looking at, you need to figure out how to have two nodes trust each other. This means that you have to identify a separate thing that you trust on which to base the nodes' trust. There are two common approaches:

  1. Trusting a third party. This is the model that we use for most websites we visit. When our computers are created, the trusted third party creates the device to already know about and trust certain entities, like Verisign. When we contact a web site over HTTPS, the browser automatically checks if Verisign (or another trusted third party certificate authority) agrees that this is the website that it claims to be. The magic of Public Key Cryptography and how this works is a whole separate topic, which I recommend you investigate (just google for it :) ).

  2. Separate, secure channel. In this model, we use a separate channel, like an administrator who transfers the secret from one node to the other. The admin can do this in any manner s/he wishes, such as encrypted data carried carried via USB stick over sneakernet, or the data can be transferred across a separate SFTP server that s/he has already bootstrapped and can verify that it's secure (such as with his/her own internal certificate authority). Some variations of this are sharing a PGP key on a business card (if you trust that the person giving you the business card is the person with whom you want to communicate), or calling the key-owner over the phone and verbally confirming that the hash of the data you received is the same as the hash of the data they sent.

There are on-line key exchange protocols - you can look them up, probably even on Wikipedia, using the phrase "key exchange", but you need to be careful that they actually guarantee the things you need to determine - like how does the protocol authenticate the other side of the communication channel. For example, Diffie Hellman guarantees that you have exchanged a key without ever exchanging the actual contents of the key, but you don't know with whom you are communicating - it's an anonymous key exchange model.

You also mention that you're worried about message replay. Modern secure communication protocols like SSH and TLS protect against this. Any good protocol will have received analysis about its security properties, which are often well described on Wikipedia.

Oh, and you should not create your own protocol. There are many tomes about how to write secure protocols, analyses of existing protocols and there security properties (or lack thereof). Unless you're planning to become an expert in the topic (which will take many years and thousands of pages of reading), you should take the path of least resistance and just use a well known, well exercised, well respected protocol that does the work you need.

atk
  • 9,244
  • 3
  • 32
  • 32