Python Control Server – Traffic Encryption (2 of 8)

[ Part 1Part 2Part 3Part 4Part 5 – Part 6 – Part 7 – Part 8 ]

What’s up guys?

Welcome to part two of the Python control server series.

In the first part of the series we made a simple plaintext control server. It allows you to run commands and control your systems from a distance.

This time we’re stepping it up and adding AES encryption to it.

Traffic Encryption

Since the plan is to eventually add more functionality to our server such as file transfer and reading documents over public networks, traffic encryption is definitely essential to the project.

Imagine you are downloading a file from your computer at home to your laptop using a hotel’s public wireless connection. It’s hard to feel safe about it without using some form of encryption.

For this and other reasons, we’ll be using pyAesCrypt to encrypt the connection to our server using AES both ways (server and client).

I have a few posts already on the topic. One specifically for recursive file encryption and another for encrypted data over the network.

This time, however, we’ll be using in-memory encryption stream to make sure our connection is safe from the server to the client and vice versa.

I am however running a little short on time today so I’ll be jumping into the code right now and get straight to the point – download below.

Dive Into The Code

The main code for encryption/decryption is the same on both the server and client so I’ll simply go through it once here:

# Lets set buffer size and password
bufferSize = 1024
password = 'wearebackboys'

# Encrypt data
def encryptData(msg):
	if sys.getsizeof(msg) >= 800: msg = 'Command output too long.\n'
	pbdata = str.encode(msg)
	fIn = io.BytesIO(pbdata)
	fCiph = io.BytesIO()
	pyAesCrypt.encryptStream(fIn, fCiph, password, bufferSize)
	# Data to send (bytes-like)
	dataToSend = fCiph.getvalue()
	return dataToSend

# Decrypt data
def decryptData(msg):
	# Initializing ciphertext binary stream
	fCiph = io.BytesIO()
	fDec = io.BytesIO()
	# Convert to bytes, get length and seek to beginning
	fCiph = io.BytesIO(msg)
	ctlen = len(fCiph.getvalue())
	# Decrypt stream
	pyAesCrypt.decryptStream(fCiph, fDec, password, bufferSize, ctlen)
	decrypted = str(fDec.getvalue().decode())
	return decrypted

To start off you’ll need to set a buffer size. We are using 1024 bytes, since that is the amount of data being sent/received in the sockets.

Then you should set a password that matches both on server and client.

In the encrypt function we are checking for data only up to 1024 bytes, and if the data passes that amount we’ll cancel the message – this will be implemented in the next part and I’ve hinted at the solution for it on my video: encrypted data over the network.

Aside from that the process is pretty straight-forward. We’ll declare the BytesIO objects that we need to pass for encryption. Run the main encryptStream function (takes input, output, password and buffer size).

Note how on both functions we’re returning the data so we can using it inside the socket send methods for easier implementation in the code.

The decryptStream function is the same thing in reverse order. Only difference is you’ll need to pass the additional length argument.

More information about these functions to be found in the documentation for pyAesCrypt or my previous video about data over the network.

Download Code

That’s it for today guys, download the code, check it out.

Gotta run, see y’all next time!