I wish to transfer data securely from an arduino (a microcontroller) to a server.

The obvious solution is probably to use TLS, but arduino does not have the capability to run it.

I did not find any other lightweight implementations either that could run on an arduino with the the needed features (encryption and authentication).

However, I have found implementations of both AES128-CBC and HMAC-SHA256 that can run on an arduino. I would like to use these algorithms.

The problem is that AES requires an initialization vector. This is hard to achieve using a microcontroller and I do not wish to string up some hardware random number generator.

Enter the danger zone:

Ask the server to generate one for me.

Assuming there are two keys that both the arduino and the server have in memory:

  1. Send some sort of HELLO SERVER packet to the server
  2. The server generates a random initialization vector using /dev/random, appends a HMAC-SHA256 hash to it, and sends it back to the arduino.
  3. The arduino verifies the received IV with the HMAC-SHA256 hash.
  4. The arduino encrypts the plaintext using AES128-CBC (with the IV it received) and then runs it through HMAC-SHA256, appending the resulting hash to the ciphertext.
  5. Arduino sends the result to the server
  6. The server verifies the HMAC and then decrypts the ciphertext using the IV it remembers.

Does this sound viable at all?

Would I need to use two unique pre-shared keys? One for AES and the other for HMAC? Does using one key only make the security of AES dependent on SHA256?

Are there other ways to achieve what I want without additional hardware?

Disclaimer: This is just for fun learning purposes: my temperature data isn't that sensitive.

1 Answer 1


Your idea of offloading IV generation to the server seems logical and fine. There are just a few things that I would like to add to make it more secure.

  • General rule of thumb is to use different keys for hashing and encryption.

  • What will you do if the keys used for HMAC/AES are compromised? Unfortunately, I don't have any easy to maintain/implement solution to that problem yet.

  • In the current scheme, someone can replay the HELLO SERVER packet and keep generating random IVs from your server. You can protect against it by encrypting your HELLO SERVER message by a fixed AES key and sending a timestamp in your packet.

  • You can maintain a timestamp/nonce in all of the messages to ensure nobody replays your temperature values/IVs. This will require your client and server to have a sliding window implementation for replay detection.

  • One possible optimization can be that the server generates a AES key and an IV on the client registration time. This will ensure that even if your key is leaked, the Arduino devices that are already registered are not affected.

For all of the above points, consider the tradeoffs of security/developer time and then make a decision.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .