Don’t Be the Weakest Link: Auto-Generated Self-Signed Certificates For Embedded and IoT Devices

Don't be the weakest link!

A New Way to Protect Your IoT and Embedded Devices

The saying goes, “A chain is only as strong as its weakest link.” Nowhere is this more fitting than in security, and believe us, nobody wants to be the weakest link. This is especially true when it comes to security for your embedded systems and the data they collect and transmit. Unfortunately, few instances of ensuring all of your bases are covered are as challenging (and daunting) as it is in the embedded and IoT world. In this article, we will discuss how NetBurner can help solve this problem for you by offering auto-generated self-signed certificates with literally a single line of code, but more on that later.

The Secret's Out. Try Our ARM® Embedded Dev Kit Today.

Netburner ARM Cortex M7 embedded Development Kit for IoT product development and industrial automation.

Or, learn more about NetBurner IoT.

The Scale of IoT and Embedded Systems

Global Network
The number of connected devices continues to explode.

If you do some research on the predicted number of IoT devices expected to be connected in the next few years, the results you’ll find are pretty staggering. While there is a bit of variation (as is reasonable when it comes to predictions), you would be hard-pressed to find anything reliable that isn’t well into the billions. For example, IoT World Today published an article earlier this year that suggested there would be around 41.6 billion devices connected by the year 2025.

Now, many of these will be connected over different types of networks using different protocols. However, it’s safe to assume that many of these will be connected protocols that take advantage of the SSL/TLS security protocol, such as our old friend TCP/IP. Of course, this presents some problems for those deploying hundreds or thousands of embedded devices.

There’s a good chance that some of your devices will act as a server, listening for systems to initiate a connection (I’m looking at you, IoT gateways). If this is the case, then each of those devices will need a certificate/key pair to use during the SSL/TLS handshake. Of course, the same requirements might be true for your clients as well. It’s also possible the server you want your embedded systems to connect to enforces Client Authentication (and they really should). In this case, all of the devices trying to connect to it will need to offer up certificates of their own.

What To Do?

There are currently a couple of theories on how to handle certificates for a large number of embedded devices, and most of them to date range from poor to cringe-worthy. If you do some digging, you’ll undoubtedly find many kindred souls who are out there trying to get a handle on this very problem.

The Dream

In an ideal, security-minded Utopian society, each device would have a personal certificate that was signed by an approved Certificate Authority (CA). However, going through this process for a single website is often a headache (not to mention potentially expensive), let along doing it for thousands of devices.

SSL Verification
Do you want to do this for 1000 devices? Us either.

Closer to Reality

A less ideal, though still, effective solution is to generate a self-signed certificate for each embedded system or device. Removing the CA from this process certainly speeds it up. The cost of course is being unable to validate ownership of the certificate. Even in this scenario, the problem remains that the number of certificates you might need to manage is overwhelming. There are some very nice tools and scripts that you can use to create self-signed certs. That said, in the end, you will still face the problem of uploading them to each of your devices. That’s only fun for the first hundred modules or so.

Fortunately, we have come up with a solution. While its suitability for a production environment will depend entirely on your specific circumstances, it will at least give you a “secure” foundation on which to build. With our NNDK 3.x toolset (and coming soon in 2.9.x), it is possible to build applications that will automatically generate self-signed certificates on the device at runtime. You no longer need to run scripts to generate a certificate signing request that will then be used to generate a certificate that you will then need to compile in or manually uploaded to your device. Whew… even typing it out is annoying. The whole process just got a whole lot simpler. How simple? Let’s find out.

The NetBurner Solution

As mentioned above, to help you put your best foot forward when trying to tackle security for your embedded and IoT devices, NetBurner now offers the ability for onboard auto-generated self-signed certificates. What this really means is that with minimal effort (a single line of code, in fact), NetBurner modules running applications that function as a server can automatically generate a self-signed certificate.

Generating certificates for your IoT devices never felt so good.
Auto-generated Self-Signed Certificates? Oh yeah! (Source: Giphy)

We designed this feature to allow engineers to have maximum control over the certificates that are used by their devices. There are three primary use cases to consider here. For example, let’s say that the module boots up and is instructed to start a secure web server (HTTPS), or listen for secure incoming connections. The following are the most common situations that would occur.

  • The module will contain a manually loaded or compiled in certificate. This is the most common scenario. In this case, no certificate generation happens. The certificate that was loaded or compiled in will be used for all secure connections.
  • The module will not contain any pre-loaded certificates. In this case, the module will realize it needs a certificate to accept secure connections. It will then generate a self-signed certificate on the spot. This will be used for all future connections. That is unless…
  • The module initially didn’t contain a certificate, but one was loaded at a later date. In this case, the certificate that was loaded manually would take over and be used for all connections. If this certificate were to be removed down the road for some reason, the auto-generated self-signed certificate would pick up the security sword and shield and soldier on.

Technical Details For Auto-Generated Self-Signed Certificates

We should take a moment to share a few things about this process. Certificates generated with this functionality are good for ten years. If the certificate should happen to expire, the module will detect it the next time the SSL server is initialized. It will then generate a new certificate automatically to replace it. These certificates live in non-volatile memory, which means that they will survive if the device is powered off.

When generating the certificate, the random number generator will need to be properly seeded. The module does this by analyzing serial and network traffic. Pinging the device or visiting the device’s config page from a browser will speed this process up.

By default, the certificate is generated using ECC with SECP384R1. This can be changed to an RSA key by undefining ENABLE_ECCKEY_CREATE in \libraries\crypto\platform\(platform name)\user_settings.h, and then rebuilding your application. To specify what curve or RSA key length is used in certificate generation, define DEFAULT_KEY_TYPE as one of the values from SslKeyType_t.


Finally, to enable this feature, simply call EnableOnboardCertificateCreation() before you call init() in UserMain(), as shown in the code below.

void UserMain(void *pd)
    EnableOnboardCertificateCreation(); // Enable automatic certificate and key generation
    EnableSecureConfigServer(false);    // Enable secure config server, used to verify cert generation

    init();                             // Initialize network stack


    iprintf("Application: %s\r\nNNDK Revision: %s\r\n", AppName, GetReleaseTag());

    while (1)

In the example above, you can see the call to EnableOnboardCertificateCreation() that allows for onboard certificate generation. Run underneath that is a call to EnableSecureConfigServer(false). This function allows us to view the device’s configuration page over HTTPS. The false here only means that we aren’t required to use HTTPS. In this case, though, that’s how we will prove our certificate generation is actually working. After these two calls, the rest of the application is pretty basic.

Proof of auto-generated certificates.
Auto-generated certificates are self-signed. Most browsers will be annoyed.

To see this code in action, we are going to load it onto a device. After it has booted, open a browser and point it to https:/(device IP)/:20034. If you need to find your device’s IP address, head to Port 20034 will direct you to the device’s configuration interface.

Keep in mind that when you initially try to request the page, it might take a bit of time to get a response, depending on what kind of key the module is generating. Because it is a self-signed certificate, you will probably get a warning from your browser. It’s safe (just this once!) to click through this to get to the configuration page. You can verify that you’re accessing the secure page by checking out the certificate to the left of the URL (in most browsers).

Wrapping Up

Hopefully, seeing this new system has you feeling a bit better about the potential of tackling security in your IoT and embedded systems. We’d love to hear your thoughts or questions on certificate generation. We’d also love to hear any other ideas you might have about approaching security in your projects and designs. Feel free to leave a comment below, or email us directly at

Share this post

Subscribe to our Newsletter

Get monthly updates from our Learn Blog with the latest in IoT and Embedded technology news, trends, tutorial and best practices. Or just opt in for product change notifications.

Leave a Reply
Click to access the login or register cheese