1

I have a school project involving an Arduino-based sensor that needs to send sensor readings to a server via HTTP. The sensor readings do not need to be encrypted (it's okay that people know what they are) but we do want to (1) authenticate the Arduino and (2) make sure the data was not changed in transit.

After all, we don't want just anyone to be able to send sensor readings to the server, and we want to know where those readings actually came from.

I have thought of using JSON Web Tokens (which are pretty compact and can be hard-coded into the Arduino or on an SD-card) to authenticate the Arduino, but Man-in-the-Middle attacks would still be a problem if we're just using HTTP over TCP. The recommendation seems to be to use HTTPS, but I've read somewhere that an Arduino doesn't have the horsepower required for HTTP over TLS. (Is this really true? I've yet to actually try)

I've thought of the following approach and would appreciate any thoughts on whether it would actually address the problem.

  1. The Arduino has a JSON Web Token (which identifies the Arduino and contains a secret value k).

  2. The Arduino computes an HMAC for the data using the key k. Call this H.

    H = hmac(data, k)

  3. The Arduino sends the JWT, the data and H using an insecure connection (HTTP over TCP).

  4. The server receives the message from the Arduino. It decrypts the JWT, which only it can do because the JWT was symmetrically encrypted on the server. After decrypting the JWT, the server now knows k & data and can compute H, allowing it to verify the data's integrity, as well as authenticate the Arduino.

Am I wrong? Is there a better solution? Thank you in advance.

  • You would need to provide unencrypted k to the Arduino. So it might be best to not use JWT at all and only send timestamp,deviceid,measurement,hmac(timestamps+','+deviceid+','+measurement, devicekey) and keep a database of deviceids and keys. (Possibly looking at OAuth device flows for provisioning) – eckes Dec 6 '17 at 4:53
1

Since this is an embedded device and resources are limited, you can reduce this a bit.

You're already computing the signature of the data, so why not just stick the data in the JWT instead, and compute the JWT signature?

This solves a couple problems. First, the JWT is constantly changing, so the ability to replay it can be significantly reduced. Second, you're sending less data.

You need to do a bit of work on the server side to prevent replays. You can timestamp the JWT if you have a clock available to you and only accept values where the timestamp is greater than the last seen timestamp, or just use an incrementing counter in the JWT (request 1, request 2, request 3, etc.).

Speaking pedantically... at this point it's less of a JWT and more of a generic JWS payload. A JWT has specific requirements for claims inside the body such as issuer, expiration/validity, subject, etc., whereas a JWS is more or less just a chunk of signed JSON.

0

I have the same problem here. I found a solution +/- the same of mine.

My solution is when my device connect to a hardware, it generate a key, send the key back to device owner, and when the device need make something it uses this key to transfer a json data crypted with AES 256.

  • 1
    Be careful, this might not protect the integrity of the data, you need to use a mode which does that (like GCM) – eckes Dec 6 '17 at 4:50
0

Your proposed protocol has at least one weakness, it provides no replay protection (unlike, say, TLS). Since your goal is to send sensor data, this might be a problem as an attacker can keep sending old sensor data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.