Wednesday, January 8, 2020

Arduino Project One: Secure communications through the firewall

Bad luck: I broke the camera connector on my Raspberry Pi Zero W, and then I think I zapped the Pi itself. It's dead, Jim. Fortunately, I have a Pi 3B lying around, waiting to be useful, so I think I'll press it into service.

My original plan was to set up a web page on the Pi, and to communicate with the Pi through a browser or a smartphone app. That would entail setting up port forwarding on my home network's router, or as they say, "punching a hole in the firewall." And that's always a network security risk.

Today, a co-worker gave me a better idea. It stems from the work I'm doing at FreeWave with MQTT.

Use MQTT to talk to the garage door

MQTT is a data communications protocol used widely in the Internet of Things (IoT) —the world of connected appliances, automobiles, doorbells, and so on. It's intended for sporadic communication of small amounts of data, perfect for this application.

MQTT follows a client-server model. However, the server doesn't really save the data: it just receives it from clients who send it data (that's called publishing), and distributes it to other clients that have asked to see the data (or subscribed to it). It doesn't actually save any data; it's just a go-between. For this reason, the server is more of a broker than a server.

A good, widely used, open-source MQTT broker is Mosquitto. Mosquitto is ridiculously simple to set up and run in the background. So I will set up Mosquitto to run on a cloud server somewhere.

The Raspberry Pi will subscribe to garage-door-opener messages received by the broker. It will publish a couple of messages of its own, in response to the messages it receives. I can use a Corona app, a webpage, or a Python or JavaScript script to publish messages to the broker.

By setting it up this way, I can totally bypass my router.

Messages to send to the Pi:
  • Request status of the garage door (closed, or not closed)
  • Push the button, Max.
Messages to be sent by the Pi:
  • Status of the garage door is closed, or not closed
    • ... including a camera image
  • The button has been pushed 
Data security is still a concern

MQTT transactions can be sent as binary data or as plain text. Anybody who knows the MQTT broker's IP address can snoop on the MQTT messages. Once they know the message tags, they can subscribe to those tags and intercept the data. If they can intercept the data, there's the chance that they can hack the system. At the very least, they can know the status of my garage door and maybe see what's in my garage. At worst, they can open and close the door at will.

An MQTT message can contain one or more metrics, the data items being transmitted. I can encrypt the data, and then send both the encrypted data and an encryption key, so the subscriber will have to utilize the key to decrypt the data. But if I do that for the "Push the button, Max" message, then a hacker can just copy the message and use it as is to push the button. I need a key that will change regularly, and that only the Raspberry Pi knows.

So another idea is to use a challenge-response algorithm, something like this.

Me: Hey, garage door. I want you to—
Pi: Wait wait wait, here's a randomly generated key. Use it to encode your message.

Me: Here's a huge number, which I created from your randomly generated key to prove that I'm me, and my request, which I encrypted using your randomly generated key.

Pi: Good, that's the right number. Now I know that you're you. Here's a response to your message, also encrypted using the randomly generated key.

Me: Thanks. We're done.

The idea of the Pi generating a random key, and both the Pi and the client using that key to generate an encryption key, has some holes in it. The NSA can hack something like that pretty quickly, if they can figure out the key-generation algorithm. But it might be enough to defeat neighborhood hackers. I think it's at least as secure as the mechanical lock-and-key on my front door.

Counting cards

Even if a hacker can't decrypt the messages, he might be able to deduce from the pattern of messages that someone is trying to operate the garage door opener. Since the normal state of the door is closed, if a hacker sees two clusters of messages a few minutes apart, for example, he can reasonably deduce that the garage door was opened and then closed. And if the hacker sees only one cluster of messages, with no other action for a while, he can reasonably deduce that the door's status was checked, but not changed.

It's like counting cards at the blackjack table.

So it might be a good idea to have the client and the Pi swap some bogus messages once in a while, encoded, of course, and the same size as real messages, to confuse any hackers monitoring the broker.


To read the other postings about this project, click here and scroll to the end.