Contents

How to generate the AWS IoT Certificate using CSR

Overview

The X509 certificate registered in AWS is needed to connect a Device to the AWS IoT Core.

The X509 certificate is used to authenticate the IoT Device. In other words, the Certificate is a proof of identity.
To be precise, not the X509 Certificate itself, but the corresponding Private Key.
That is why the Private Key should be generated and stored in a secure way on IoT Device.

There are multiple ways to crate and register an X509 certificate in AWS. Today I will present the create a certificate from CSR (Certificate Sign Request) approach.

One of the main advantages of this approach is that the Private Key never leaves the IoT Device.
The Device creates the Certificate Sign Request and sends it to AWS. Amazon Root Certificate Authority (CA) generates a Certificate based on received CSR and returns it to the Device.
Even if someone intercepts that Certificate, that won’t be enough to connect to the AWS pretending “compromised” Device. To establish the MQTT connection both the Certificate and Private Key are required.

The below diagram illustrates the overall process to create a certificate from CSR.

/posts/aws_iot_thing_attributes/cert_from_csr.png

Sample code

Let’s start with generating the Private Key for our IoT Device:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from OpenSSL import crypto
import os

thing_name = "TestThing001"

key = crypto.PKey()

# I suggest using at least 4096 bit key
key.generate_key(crypto.TYPE_RSA, 4096)

# to protect the Private Key on the filesystem it should be readable only by the user that generated it
# mode=0o400 sets proper permissions
with open(os.open(f"{thing_name}.key", os.O_CREAT | os.O_WRONLY, mode=0o400),'w') as f:
    f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key).decode("utf-8"))
1
2
3
ls -l TestThing001.key

    ['-r-------- 1 lmtx lmtx 3272 lut 10 21:40 TestThing001.key']

Using that Private Key we can generate the Certificate Sign Request (CSR):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
csr = crypto.X509Req()

# Common Name (CN) should be equal to the Name of the IoT Device
csr.get_subject().CN = thing_name
csr.set_pubkey(key)
csr.sign(key, "sha512")

# the CSR is not confidential, so we do not have to restrict the file permissions
with open(f"{thing_name}.csr","w") as f:
    f.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, csr).decode("utf-8"))

Let’s check the content of CSR using openssl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
openssl req -in TestThing001.csr -text -noout|head -n 7


    ['Certificate Request:',
     '    Data:',
     '        Version: 1 (0x0)',
     '        Subject: CN = TestThing001',
     '        Subject Public Key Info:',
     '            Public Key Algorithm: rsaEncryption',
     '                RSA Public-Key: (4096 bit)']

Finally, we are ready to ask the Amazon Root CA to sign the certificate for our IoT Device:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import boto3

# A session manages state about a particular configuration.
# I recommend you specify profile and region - that is a good development practice.
session = boto3.Session(profile_name='train',region_name='eu-west-1')

# Obtain the IoT Client.
iot_c = session.client('iot')

# create the certificate based on CSR and set it to Active state
r = iot_c.create_certificate_from_csr(
    certificateSigningRequest=crypto.dump_certificate_request(crypto.FILETYPE_PEM, csr).decode("utf-8"),
    setAsActive=True
)

Let’s save our brand new Certificate to disk; we will use it to connect our IoT Device to the AWS IoT Core in my next post:

1
2
with open(f"{thing_name}.pem",'w') as f:
    f.write(r['certificatePem'])

We can use the openssl command to review this certificate:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
openssl x509 -in TestThing001.pem -text -noout|head -n 14

['Certificate:',
 '    Data:',
 '        Version: 3 (0x2)',
 '        Serial Number:',
 '            2f:c5:25:d3:39:10:72:d3:34:87:97:0c:5a:82:a0:e2:1c:1a:29:08',
 '        Signature Algorithm: sha256WithRSAEncryption',
 '        Issuer: OU = Amazon Web Services O=Amazon.com Inc. L=Seattle ST=Washington C=US',
 '        Validity',
 '            Not Before: Feb 10 21:43:03 2022 GMT',
 '            Not After : Dec 31 23:59:59 2049 GMT',
 '        Subject: CN = TestThing001',
 '        Subject Public Key Info:',
 '            Public Key Algorithm: rsaEncryption',
 '                RSA Public-Key: (4096 bit)']

This certificate was issued by Amazon Web Services and is valid for 27 years.

Summary

The X509 Certificate is the proof of identity of an IoT Device.
Certificate corresponds to the Private Key, which was used in the process to generate it.
The Private Key needs to be securely stored and handled with care; Certificate itself is not confidential.

In my next post, we will cover the additional setup needed to securely connect an IoT Device to AWS IoT Core and send an MQTT Message.

Support quality content❤️ Donate💰

Sign up for news: (by subscribing you accept the privacy policy)