Sometimes we have to send short command sequences and/or replies over unprotected networks. Especially when working with IoT environments. Though SSL/TLS is always preferred – sometimes it’s just too much overkill.
Here’s the situation: You want to send a command over a digital line and want to get moving without setting up complex SSL/TLS tunnels, certificates or related environments.
Of course you need encryption. So you’re using something like AES with a pre-shared key. That is: Both sides know the “password” . That’s better than nothing, but it adds significant strength if you add two features:
- A time stamp to prevent repetition attempts; and
- A variable pre-shared key.
Here’s what I am doing:
I pack all requests and answers into a JSON array and “stringify” it for easier encryption. Within the array I add status codes, requests and answer, whatever I want. I also include a UTC time stamp that will be verified and rejected on the receiving side if it is expired. If someone were to record the communications, he wouldn’t be able to simply use that encoded string to repeat the request. You could also work with serial- or sequence numbers, but that again would require to keep track of the sequence number – too much overhead. A time stamp will do just fine.
My pre-shared key is 255 bytes long and consists of random bytes. In order to select a key, I randomly select a position within this pre-shared key and take 15 bytes from that position to be used as the key (password) for this request (or answer). The binary value of the pre-shared key is added to position 0 of the encrypted payload. The receiver just takes the first byte and applies the same procedure to retrieve the key. Now you have pretty much a variety of different passwords that will significantly add to the brute force resistance of your encryption. Just make sure all other encryption parameters (like IVs, algorithms and modules) are ok.