5

I'm building a small server at home, and I'd like to have a sort of "smart" board to control its power. This board will have, at the beginning, to simply turn it on or off (more features will be added later).

This device will be sort of Arduino based (in fact it is a more powerful microcontroller, but I'm using the Arduino environment to program it).

Now, the access to all the network will be provided through VPN from the server, but obviously the switch cannot be accessed only through VPN (since it cannot be reached if the server is off, hence I will not be able to turn it on). So a direct internet access is needed for it.

I wanted to secure the operations, since allowing anyone to turn on and off my server is a bit problematic..

What I thought was using a set of pre-shared symmetric keys (thinking about AES); every time the webpage is loaded the microcontroller sends a seed (for instance the date) and the client, through JavaScript, evaluates a token to be sent along with the request encrypting, for instance, the seed and the request with the key passed in a textbox.

What do you think? Are there simpler solutions already known? How is this problem usually handled?

Please note that HTTPS is not a solution, since implementing it onto a microcontroller is quite hard...

EDIT: since some additional info were asked, here is something more specific:

the board I'm planning to use is a Maple Mini; the processor is a STM32-F103RCBT6 (72 MHz, 120 KB Flash, 20 KB SRAM). I'll be using an ENC28J60 ethernet interface (so no hardware stack).

I will forward a port from my router to it, since I want this functionality to be available from "the outer world"; the interface will be a webpage. If the flash becomes too tight, I can put the page on an external SD card.

Aurora0001
  • 18,520
  • 13
  • 55
  • 169
frarugi87
  • 159
  • 2

1 Answers1

7

To authenticate the command coming to your "smart" board, the challenge-response system you propose is suitable:

  1. a remote system R initiate communications with the board B
  2. B generates a time based nonce, and sends it as a challenge
  3. R receives it, and use a secrete key to generate a response. The response must be sent with a command. Ideally, the content of the command must be used to generate the response (response is also a signature for the command).
  4. B use the nonce, command and same secrete key to generate what should have been the response, and check if R response matches

The crypto you pick doesn't really matter, go with something basic like AES 128. The challenge B sends should be time-based, and it must not be possible to get the same challenge twice.

Most importantly: be very very careful on how you code your input parser. This is the main entry for an attacker. The best crypto in the world won't saves you if sending a malformed answer crashes your board or allows remote code execution.

Be conservative, keep your protocol very simple. Use a fuzzer to make sure any invalid stuff is rejected (negative testing). If you don't use a safe language, enable absolutely every checks and warnings your compiler can offer, use static code checker, use dynamics checking tools while you fuzz to check for any overflow or memory leak. Check how your program handles a network overload, use rate limits (eg. 1 challenge every 5 sec max, other attempts are silently ignored) and enforce memory limits. Have a watchdog.

It's a nice challenge to implement such a system, and a good learning opportunity if the consequences of a failure are not critical. Realistically, even the mildest challenge will be enough to stop a script-kiddie or a criminal wanting to do a quick buck, but the absence of attack is no proof that your system is secure. It could be because it's secure... or because nobody really tried. Keep that in mind and prepare a contingency plan.

Sylvain
  • 563
  • 4
  • 8