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.
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).
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) &amp;amp;amp;gt;= 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()) fCiph.seek(0) # 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.
That’s it for today guys, download the code, check it out.
Gotta run, see y’all next time!