Secure communication for Internet of Things (Proposal)

I’m working on embedding an Arduino and ESP8266 into my garagedoor opener. There have been multiple other projects online on how to do this but I’m not thrilled with the security of those solutions.

For this, I’m implementing a method to prevent password replay attacks and to keep the password from being sent in clear text.

Given that SSL, AES or really any public key cryptography is too expensive to be implemented on a small AVR, I’ve worked out a way to do this using digests.

Below is psudo code of what I’ll be implementing. Once it’s completed, I’ll publish this as a library for anyone to use. I would appreciate any feedback you’d have, especially if you can find any holes in this logic.

////
//Response-A
////

serverTime = 012345
secret = ‘someLongRandomString’

password = pass

digest = md5(time + secret)


FORM
password=input
digest=digest
serverTime=serverTime


////
//Request-B
////
clientPasswrord

request?requestTime=serverTime&digest=digest&requestPassword=md5(digest+password)


////
//Response-C
////
// Ensure response time window has not elapsed
if (serverTime-requestTime < 120) {

// Calcuate based on inputs from request
requestDigest = md5(requestTime + secret)

// If they’re the same, the payload has not been altered
if (digest == requestDigest) {
// We can be assured that the request was initated by our server.

passwordDigest = md5( digest + password )

// If the two matches, the password is valid
if (requestPassword == passwordDigest) {
// YAY! Do something good.
} else {
// Password doesn’t match
}

} else {
// Go away
}

} else {

// Go away
}


This example uses md5, but that can be replaced with other cheap digesting methods (sha1, etc).

In the initial response to the web browser (Response-A), a form is created with the server time and a digest composed of the server time and a long secret string.

To this, the web browser will send the form back to the server (Request-B) the time and digest unaltered and an md5 of the provided digest and the user’s password. This is to ensure that every time this form is submitted, the password will be digested to create ‘passwordDigest’ (one way encrypted).

The in response to this request (Response-C), the server will first check that the server’s current time is no greater than 120 seconds more than the time in the request. This window can be adjusted. If it’s been more than 120 seconds, the request is to be considered old and invalid.

We recalculate the digest from the time provided by the client and the secret. If that recalcuated digest is the same as the digest in the request, we can form a trust relationship between the server and client.

Once the trust has been established, the password stored on the server is digested and checked to see if it is equal to the password digest provided by the client.

If that matches, then the client has provided a valid password.

There is the possibility that the request can be replayed during the 120 second time window, but that provides a very small opportunity for attack. The timing can be adjusted as needed.

If the time is defined as the time since server boot, an attacked may be able to powercycle device (main breaker is outside the garage) to be able to game the replay window.

If the time can be updated from an NTP source, then the time will never roll back over and the opportunity for replay is further reduced.

I can see this being generalized further to a scheme for session management or managing multiple passwords.

Can you spot any flaws in this proposal?

  • Jm

mchamster: ... Given that SSL, AES or really any public key cryptography is too expensive to be implemented on a small AVR, I've worked out a way to do this using digests. ...

Let ESP8266 handle it. ESP8266 is 32bits/80Mhz/160Mhz CPU. It is a piece of cake.

sonnyyu: Let ESP8266 handle it. ESP8266 is 32bits/80Mhz/160Mhz CPU. It is a piece of cake.

I was looking at the ESP8266, but my toolchain is not yet setup to work with that architecture. It'll be too much time to retool just to open my garage door.

You need to include a nonce in case the clock granularity is too course.

The 120 second window is ridiculously large. The round trip time for the exchange (plus a bit) is much more reasonable.

my toolchain is not yet setup to work with that architecture

One download away. http://esp8266.ru/esplorer/ http://forum.arduino.cc/index.php?topic=311117.0

[quote author=Coding Badly link=msg=2180569 date=1428649062] You need to include a nonce in case the clock granularity is too course.

The 120 second window is ridiculously large. The round trip time for the exchange (plus a bit) is much more reasonable.

[/quote]

Agreed.

jremington: One download away. http://esp8266.ru/esplorer/ http://forum.arduino.cc/index.php?topic=311117.0

I took your advice. Currently writing this for esp8266. It's a rather compelling platform. The built in watchdog timer is a pain, but it's a nice big hammer with the (immature) libraries get stuck in a loop.

Hi mchamster,

Any news on that library ?