We're working on AWS-IoT using an STM32 microcontroller.

Till today, we were writing the certificates to the flash and locking the flash from external reading. As the application code increases, we're getting lesser space on the flash so we were planning to move the certificate externally on an SD card / EEPROM and read whenever it was needed before connecting to AWS-IoT.


  • The policy written for the thing will allow only devices with particular names to connect on that particular certificate.

  • The thing is allowed to publish to only 2 channels (it's name and a data feed channel) which is connected to a data processor which will ignore any rogue packets coming to it.

  • If the thing publishes/subscribes to any other topic, AWS will disconnect the thing immediately.

If I detect a device is stolen/rogue we deactivate the key from the server.

What can an exploiter do with the certificates (RootCA, server key, client key)?

Is it a bad practice to keep certificates for such usecase on an external storage which can be accessed by an exploiter?

  • Were you using Read protection Level 2 (the permanent one) or Level 1 to make the flash read-only?
    – Aurora0001
    Feb 10, 2017 at 16:27
  • 1
    What exactly do you mean by "certificates"? Do you mean the public certificate (e.g., public key, and signature from a trusted root)? Or do you mean the corresponding private keys? Normally certificates is understood to mean the former, but your remark about "server key, client key" and your question makes me think we'd better double-check what you mean.
    – D.W.
    Feb 10, 2017 at 23:33
  • What flash device are you using? Most the read prevention can be turned off via the spi interface with a register in the flash. The purpose of the read prevention is to prevent software on the cpu from accessing it but anyone with physical access to the flash can turn that off. Feb 17, 2017 at 12:21
  • Oh yes onboard flash for arm chip, dissreguard my earlier statement, which was for spi flash ic or external flash. Feb 17, 2017 at 16:45

4 Answers 4


You mention “certificates”, but from context, I think you're referring to two different things.

  • Your device has a private key, which is unique to this device and not known outside the device. This key identifies your device. Anybody who can access that key can impersonate the device. That means that they can, in particular:

    • Publish valid, but incorrect data on the channels that your device is legitimately authorized to publish to.
    • Publish invalid data that will get the legitimate device banned.
    • Possibly, depending on the use case, expose some private information of the owner of the device.

    This private key had better remain confidential.

  • Your device probably has at least one public key, which allow it to recognize which servers it's talking to. It's ok if anybody can read this key: it's public. But an attacker should not be able to modify the key. Otherwise, they could communicate with the device and impersonate the server. This could allow them to do things like:

    • Push a firmware update to the device.
    • Push a configuration update to the device.
    • Make the device upload its data to a different location.

The good news is that this threat analysis is actually not very relevant. You do not need to sacrifice any security! (At least not confidentiality and authenticity properties — if you store stuff externally, then availability takes a hit, because that's one piece of the system that could go missing.)

As long as you have at least 128 bits of storage that you can write to at least once, which you have and more, you can implement a secure remote storage solution. Use the limited-space on-device storage to store a secret key. This secret key must be unique per device; the STM32 has a hardware RNG, so you can generate it on the device during first boot. If your device didn't have a hardware RNG, you could generate the key in a secure off-device location and inject it onto the device.

With this key, use authenticated encryption for things that you store off the device. When you want to read some data from external storage, load it, decrypt-and-verify it. When you want to write some data to external storage, encrypt-and-sign it. This guarantees that the data is as confidential and authentic as the data in the internal storage.

Authenticated encryption is enough to guarantee the confidentiality and authenticity of the data, but it doesn't quite guarantee its integrity.

  • If there's more than one chunk of data, then when the device reads back a chunk of data, it can't be sure that this is the correct chunk. Solution: include a unique identifier in the content of each chunk (e.g. start each chunk with one of "AWS-IoT private key.", "configuration CA certificate.", "publishing server CA certificate.", "user personal data.", …).
  • If you update the data at some point, then when you read it back, you can't be sure that you're getting the latest version of that data. If someone can modify the external storage, they can't put fake data because that would fail the authenticity check, but they can restore old data, because what used to be authentic is still authentic. Solution: in each data chunk that is stored externally, include a counter which you increment each time you write a new version of that chunk. When you read a chunk back, verify that it's the expected version.

To avoid bricking a device in case the external storage is damaged or otherwise lost, in the limited space you have space on internal storage, you should give priority to whatever is needed to reset the device to a “good” state, e.g. a factory reset. The second priority will be performance considerations.


A little bit of context

Since you're using MQTT with AWS IoT, you're expected to use X.509 certificates for authentication and security. Amazon have a little bit of guidance about how you should secure your certificates, so I'll quote that here:

Certificates enable asymmetric keys to be used with devices. This means you can burn private keys into secure storage on a device without ever allowing the sensitive cryptographic material to leave the device.

Since you're currently using the STM32's Read Out Protection (RDP), all but the most determined attackers will have trouble accessing your certificates in your current scheme:

The global Read Out Protection allows the embedded firmware code (preloaded in the Flash memory) to protect against reverse engineering, dumping using debug tools or other means of intrusive attack.

  • Level 0 - No protection (default)
  • Level 1 - Flash memory is protected against reading by debugging or code dumping by the RAM loaded code
  • Level 2 - All debug features are disabled

Is external storage going to be secure?

It probably isn't as secure. If your client's private key is stolen, an attacker can send data that appears to be from your device, when it actually isn't. Although it's not clear what data you're sending, any untrusted data can be a security risk.

Which bits do I need to keep private?

When you create a device certificate on AWS IoT, you should see an image like this:

(source: amazon.com)

Image from the Create and Activate a Device Certificate page of the AWS IoT documentation.

The private key is the thing you really need to keep... private, and should definitely be stored on the read-protected memory if possible. The public key and certificate are designed to be shared, so if you're running out of space, you can safely move those to external storage. You can get a little bit more context on the page How does SSL/TLS work? at Information Security Stack Exchange and Public-key cryptography on Wikipedia. I think I'd be doing you a disservice if I didn't include this image to explain why the private key needs to be secret:

Public key cryptography.

Image from Wikipedia, released into the public domain.

Your device's public key is what AWS IoT uses to sign messages to send to your device (but it does not prove who is sending the message). So, really, it's not a huge disaster if someone steals the public key, because it's not meant to be a secret.

The private key is what your device uses to decrypt messages, so it's a slightly bigger problem if an attacker steals this.

You also asked what would happen if the attacker stole the RootCA certificate. If someone stole AWS IoT's private key, it would be disastrous, but the RootCA certificate on your device isn't that. The RootCA.crt that Amazon give you is completely public, and the purpose is so that you can verify that you're not being attacked in any way (most likely a man-in-the-middle pretending to be AWS IoT's servers).

What damage could a hacked device do?

Your stolen device can only perform the actions listed in the policy. Try to follow the principle of least privilege; only grant your device the privileges it absolutely needs, so if the worst does happen, it can't wreak havoc too much. For your specific case:

The thing is allowed to publish to only 2 channels (its name and a data feed channel) which is connected to a data processor which will ignore any rogue packets coming to it.

That's good. Any attack should be isolated to just the two MQTT topics that the device can publish to, so it won't cause large scale harm.


Ideally you want your overall system to have a design such that dissecting a single unit breaks only that unit, and not the system in general.

Especially if you are storing keys in a distinct memory such that they cross a standard electrical interface between chips, then they should only be keys that are already safe to publish, or unique to that particular physical instance of the device.

If an individual key is extracted from a single device, and starts being abused or showing up in a volume of traffic that has to be from multiple unauthorized clones, then you could ban that key on the server side.

Your keys should of course have the property of not being something that an unauthorized party can either guess from a few extracted examples or generate their own original compatible instances of - ie, you either need a record of the keys you have generated where valid ones are only a small and unpredictable part of a huge possibility space, or else you need to sign the keys you generate and make your system only accept a key in combination with its proof of signature.

  • Thanks for your notes, how we've planned it on the receiving end of the MQTT broker is 1. If you post to another channel which you are not authorized to or 2. If you post rogue data into the proper channel at uneven or 3. We know the device is hijacked (when the device is opened : hall effect sensors) THe keyset on AWS-IoT is destroyed making that keyset useless. SO if you hack one device/ get the key of one device you will not get to do much as the policies are very strict for which topics the device can use (it's limited to 2) and what data you pass thru. Feb 18, 2017 at 5:17

You should try to keep to client key secret (but understand the implication of loosing it(1), as described in the other answers). The server public key, and the AWS public certificate are important to secure at the device end not because you want to keep then secret, but because by replacing the AWS certificate (on a compromised device) an attacker can persuade the device to carry out an exchange with the attacker's host, or to man-in-the-middle your communications to AWS.

By doing this (2), an attacker can strip out the TLS security which may result in sufficient reduction in security that they can reverse engineer the client key.

By this reasoning, the only key which it is safe to expose in an external memory device is the server public key. Changing this (3) would only allow your device to be forced to connect to a rogue AWS service which is presumably hard to engineer access to. Even leaking just this key might allow someone to snoop or fake some transmissions (for example if the TLS layer can be somehow downgraded).

So in summary, the risk is not simply in leaking information, there is a risk if the (supposedly trusted) firmware can be provided with un-trusted secure information.

  • 1
    Interesting point, but as to your last, an attacker changing out the server's public key on a device in their possession would presumably then allow it to connect through an imposter proxy having the private match of the replacement key installed on its downstream side, that proxy could then transparently forward traffic to the real server while recording it all at the point of transfer between the legitimate and imposter crypto sessions. This wouldn't even be original tech; such boxes are sold to facilities which require devices on their network to trust their imposter certificates. Feb 10, 2017 at 19:03
  • I think you're describing my 2nd point here. Isn't this 3rd key used below the TLS protocol to further encrypt the transmitted data over the trusted link? Feb 10, 2017 at 19:35
  • Normally the "trust our proxy's imposter certificate" attack is used to break TLS but it could be basically used on anything where you can obtain/replace enough of the information to impersonate each endpoint to the other. Feb 10, 2017 at 19:41
  • What makes you think that replacing the public key will let someone reverse engineer the client private key? That's not how TLS works. Public-key cryptography doesn't work that way. It might enable man-in-the-middle attacks, but it doesn't enable the man-in-the-middle attacker to extract the client's private key.
    – D.W.
    Feb 10, 2017 at 23:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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