Reputation: 1357
I would like to establish a secure NSA proof connection between two peers with perfect forward secrecy and everything else one would expect.
What is the best way to do this in python so that its standards compliment and I could easily communicate with a peer reimplemented in a different language.
It can be assumed the peers know each others ip/port before hand and also know of each others secp256k1 ECDSA public key that can be used to authenticate once the connection is established.
Just to be clear, I need both sides of the connection. The code for the peer awaiting the connection and for the peer initiating the connection.
Upvotes: 5
Views: 11837
Reputation: 23480
I'll answer this as technically correct as possible, but my terminology and memory of all the encryption letter-combinations is vague even tho I've studied them for years (lack of long term memory causes this hehe).
To begin with this is a multi-part problem and not really specific to Python. Hence my comment above.
Well a socket is the most fundamental way to do it.
These days you have websockets, sockets and all kinds of high-level communication tools, but they all rely on a basic socket (most likely over IP+TCP packets).
So I'd reccomend you to stick to sockets, unless you know the peers you're talking with uses something specific, then stick to that.
In most cases, you want to stay as legacy as possible without lowering your security. This means you'll probably have to stick to TLS (Do.. not.. I repeat, do NOT use SSLv*. Unless you know why you need to, do not!)
Python (and other languages) have nice wrappers for this.
One example how to do it would be:
import socket, ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com')
ssl_sock.connect(('www.verisign.com', 443))
This wraps your plain unprotected socket in a TLSv1
enclosure between you and a HTTPS enabled web-server. This is one of the most common and secure ways to protect your data-layer.
In Python, the way to add additional security to the socket is to pass a specific cipher combination to the wrapper. like so:
ssl_sock = context.wrap_socket(s, ..., ciphers=None)
For instance, ... ciphers=TLS_RSA_WITH_AES_256_CBC_SHA|TLS_RSA_WITH_AES_128_CBC_SHA)
if you only want to allow RSA AES 256
and RSA AES 127 CBC SHA
in your communication. All other ciphers will be discarded and the connection will break.
WHen defining ciphers you're immediately narrowing down your options to communicate.
A lot of software still uses legacy ciphers and some of the software is so out of date that they havn't even updated to TLSv1
yet and there for is not even aware that some ciphers exist.
Conclusion: This all boils down to what you want to communicate with and what software they use.
To be honest, there's no real way of knowing what they can and can't break/decipher.
If you want to be 100% safe, either you're a mathematical genius and you invent your own algorithm/cipher that you're sure that they don't know about.. yet.. And you constantly change it to stay one step ahead.
Or you stick to the most likely secure (and complex) algorithm there is.
I'd google one time pad if I were you and try to implement something along those lines. It's your best bet of staying out of the standard filter techniques used by infiltrators (NSA counts as one).
Upvotes: 6