2

I have a hub that communicates with an IoT device and needs to change the encryption key on that device at frequent intervals.

Messages are AES-256-CBC encrypted using the old key, and the new key is included in those messages.

Once the new key is sent, I need to be absolutely sure that the hub and the device are in sync on what key is being used. Why? The connection can drop at any time.

Given that, here are some things I've thought of:

  • Hub sends key, updating its own, then the device updates to the new key if it receives it. (What if the device doesn't receive the key?)
  • Hub sends key, waits to update, then the device updates its key, then sends back a 'Key received', upon which the hub updates its own. (What happens if the device's message back never gets received?)

It seems to me that no matter what, there's a final communication that can cause a party to not confirm an update. Is there a way to make sure?

  • 3
    You might find en.m.wikipedia.org/wiki/Two_Generals'_Problem applicable here... – Matthew Jan 18 '17 at 22:19
  • @Matthew "The Two Generals Problem was the first computer communication problem to be proved to be unsolvable." That's not encouraging! So how do people deal with these problems in practice? – sscirrus Jan 18 '17 at 22:27
  • Define an acceptable level which is less than absolute, in some cases. Send the new key with several messages before switching to it, so there would need to be multiple losses before complete failure, for example - not absolute, but might be good enough. – Matthew Jan 18 '17 at 22:32
  • @Matthew Do you know of a 'standard' that's used for these applications? I'm sure this is a very common issue, is it not? – sscirrus Jan 18 '17 at 22:49
1

I'm assuming you're using HMAC or authenticated encryption so that the messages are immune to modification and so you can cleanly detect a failed decryption.

  1. The hub has a list of connected devices, and for each connected device, the active key to use in messages to it, and a list of additional keys to try to use to decrypt messages.
  2. The hub decides on a new key, and for each connected device, adds it to the end of the list of additional keys. (Easy improvement by making a minor change here: you could instead create a new separate key for each device. You don't need to share keys between devices.)
  3. Whenever there are a nonzero amount of additional keys for a device, the hub periodically sends a message (encrypted with that device's active key) containing a request to switch to a new key (the last key in the additional keys list).
  4. Whenever the hub receives a message from a connected device, it will try to decrypt it with the active key and then each of the additional keys until decryption succeeds. If decryption succeeds with one of the additional keys, then replace the active key with that key, and then remove that key and all keys before it from the additional keys list.

Each device only needs to remember a single active key at a time.

This should mean things continue to work even in the scenario where the hub cycles between keys A->B->C, and a device doesn't confirm the switch to key B until after the hub has announced key C.

  • I have not been using HMAC, so I'm looking into Fernet. The idea about having multiple keys and trying them sounds more or less foolproof, so I'll look into that. Thanks. – sscirrus Jan 18 '17 at 23:48
1

Real world users of cryptographic keys will probably give you the following advice:

  • For each copy of a key that is issued, the successful (intact) receipt of that key has to be acknowledged back to the issuer.
  • Adoption of a key for usage can only be allowed to occur when all recipients have confirmed receipt.

As well as supplying the bits that compose the key (128 bits, 256 bits or whatever it is), it is helpful to supply metadata that identifies the key in a way that is unique to each key within your system, and preferably including the planned date of adoption. This metadata should be bound to the key bits, so they don't get separated, for example they are part of the same data block, with the metadata as a "header" part.

Encrypted data should be formatted to identify the key being used to encrypt it. Then each remote node can detect when the Future key has become adopted for usage (i.e. is now the Active key). The formerly Active key can then be scheduled for secure erasure from the local storage at that node.

This implies then that each node has to keep track of the key that is currently adopted (Active), and the next key it has been issued with (Future). At the planned date/time of adoption, the central node responsible for the distribution can decide to adopt the Future key if every node that requires it has confirmed receipt of it (e.g. by quoting back the metadata in an Acknowledgement message). This requires the central node to trace, for each key, which nodes it has sent a copy to and which nodes have confirmed receipt.

This is really the simplest model. If your nodes are more highly trusted, you can issue a pipeline of more than one Future key, with later and later adoption dates given in the metadata.

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.