How to Provision and Store IoT Device Certificates

Originally published at: How to Provision and Store IoT Device Certificates - Golioth

Every IoT device should operate over an encrypted channel. But how exactly does that security work as your fleet rapidly grows? Our recommendation is to use certificate authentication to deliver strong encryption while solving common fleet management problems. Today we’re showing how to provision and store IoT device certificates. Certificate Authentication based on ECDSA Golioth uses ECDSA encryption. You generate a root certificate and private key, use that key to sign all of your device certificates, then upload your public root certificate to Golioth. The last piece of the puzzled is placing a unique device certificate onto each device. One method of doing so is to store the cert on a filesystem in non-volatile storage (NVS) that is separate from the firmware itself. Golioth has sample code to show you how, and that’s the subject of today’s video. Root and Device Certificates Generating the certificates is beyond the scope of this post, but the process is well-documented in the certificate authentication section of the Golioth docs. As a result of this process you will upload the generated public root certificate to Golioth. This lets Golioth securely connect to any device that uses certificates signed by your private root key. Every device you put into the field needs to have a unique public/private key pair signed by your private root key. That device key and device certificate is what we store on the device file system. Storing Device Certificates in a File System Zephyr RTOS includes a filesystem which we have turned on in our certificate-provisioning sample code. Once the firmware is flashed to the device, use the Zephyr shell to create a directory in which the credentials are stored. This…

1 Like

Great post @mike !
Is there an instruction guide on how to load certificates with esp-idf ? (NVS or Filesystem).
Additionally I was wondering if there is a way to provide the certificate to the end device via CSR, maybe with the help of a Secure Element to generate a pair of keys and the CSR itself.
This way we could avoid to load individual certificates to the end device on the production floor. Thanks!

1 Like

Hi @andrea.longobardi!

We don’t have an example for loading certificates using ESP-IDF (but we should! I’ve created a task for us to add one).

Because there are so many ways to provision and store certificates, and our goal is to support them all, the Golioth SDK doesn’t require any particular method. You could use XModem/YModem or something similar, and store it in either NVS or a filesystem (ESP-IDF doesn’t have a file transfer protocol built-in, but there are some examples out there).

It would certainly be possible to generate the key pair on the device, create a CSR, sign it, and then load the certificate back on to the device. Golioth does not provide a private CA service that can issue certificates, but there are several out there or you can roll your own. However, we still recommend loading certificates on the production line as the most secure and robust option (whether generating key pairs on the device or not) - otherwise you either need to hardcode a universal access token into every device or you need to have an unauthenticated endpoint for creating certificates, and in our experience there are often more unexpected issues when part of the provisioning process is performed outside the controlled environment of a production line.

2 Likes

Hi @sam !
Thanks for your feedback. We have solved this with some scripts that generates device specific certificate/key and put into an NVS partition bin file (that we can even encrypt if we want to).
We will evaluate if using a UART to upload certificate/key will give us any advantage, thanks for the suggestion!

2 Likes

Awesome! That sounds like a great solution. I would probably stick with that instead of using UART - using a programmer to directly write the flash should be faster and more reliable.

I am exploring industry best practices for storing root certificate in the device during production time. I am fairly new to this subject with no prior experience in certificate management. I have an ARM Cortex-M33 based MCU from NXP and I would like to know how to add certificate to a brand new hardware during production? I am using Zephyr as well.

There are various approaches that can be used to add certificates to brand-new hardware during production. Generally, there are two considerations one has to take into account: where are the certificates stored (file system, secure element, …) and how are they transferred to a device (serial, programmer, …).

I would suggest you start by creating a file system and a directory where the certificates will be stored; take a look at our certificate provisioning sample on how to do that. Afterward, use mcumgr to manually send certificates over a serial connection and store them to a previously created directory in the file system. This way, certificates will continue to exist in the Flash memory even if the firmware is updated.

In a production scenario, the directory creation process should be automated without the need to use the Zephyr Shell, and instead of manually transferring certificates with mcumgr, you can write scripts to take advantage of the mcumgr command-line tool to automate this process further when a new device is connected to a PC host.