AWS IoT relies on device certificates to authenticate connections from the Internet. Connections to AWS IoT are not authenticated unless an appropriate device certificate is provided. I want to create, sign, and use my own X.509 device certificates for authenticating device connections to AWS IoT.

AWS IoT provides multiple options for using private keys and certificates, including:

  • Having AWS IoT generate your public/private key pairs and certificates.
  • Generating your own public/private key pairs and have AWS IoT create the certificates for them.
  • Generating your own public/private key pairs and certificates. This option is the subject of the article and requires you to register a CA certificate with AWS IoT as described here.

To use your own X.509 certificates, you must register a certificate authority (CA) certificate with AWS IoT. After you have registered the certificate, you can upload any device certificates previously signed by the CA certificate and/or use the CA certificate to sign additional device certificates. You can register up to ten CA certificates with the same subject field per AWS account per region. This allows you to have more than one CA certificate to sign your device certificates.

This example describes how to create a self-signed device certificate to authenticate a connection to AWS IoT. The steps were completed on an instance of Ubuntu Linux with the following prerequisites installed:

Prerequisites

1.    The AWS Command Line Interface (CLI) – For information about installing and configuring the AWS CLI, see Installing the AWS Command Line Interface.

2.    openssl – openssl is installed on Ubuntu Linux by default. You can run the following commands from the console to upgrade to the most recent version of SSL:

sudo apt-get update

sudo apt-get upgrade openssl

1.    Ruby – For information about installing Ruby, see Installing Ruby.

To install Ruby on Ubuntu, run this command from the console:

sudo apt-get install ruby-full

Verify that the version of Ruby installed supports OpenSSL 1.01 or higher:

ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'

Install the MQTT ruby gem by running this command from the console:

sudo gem install mqtt

Steps

These steps include several console commands that generate multiple files; consider creating a new folder and running all of the commands from the new folder.

1.    Download the Verisign root CA server certificate used to authenticate the AWS IoT server.

Your device authenticates connections to AWS IoT with the Verisign root CA server certificate. Download the Verisign root CA server certificate from Symantec by running this command from the console:

curl https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem > iotRootCA.pem

Note

Only the Verisign root CA server certificate can be used to authenticate the AWS IoT server. You cannot use your own CA certificate to authenticate the AWS IoT server.

2.    Create a self-signed CA certificate.

Use the openssl genrsa command to generate an private key for your CA certificate:

openssl genrsa -out myCAprivatekey.key 2048

For more information about using the openssl genrsa command, see genrsa.

Note: The openssl genrsa command is superseded by the openssl genpkey command.

Use the openssl req command to create a self-signed root Certificate Authority (CA) certificate with the private key you generated. You will be prompted to enter a country name, state, locality (city), organization name, organization unit name, common name, and email address.

openssl req -x509 -new -nodes -key myCAprivatekey.key -sha256 -days 1024 -out myiotCAcert.pem

For more information about the openssl req command, see req.

3.    Register and activate your CA certificate.

Follow these steps to register and activate your CA certificate.

Use the AWS CLI to get a registration code from AWS IoT. This will be used for the Common Name (CN) field of the private key verification certificate.

aws iot get-registration-code

The unique, randomly generated registration code that is returned is bound to your AWS account and does not expire unless you delete it.

For more information about the iot get-registration-code command, see aws iot get-registration-code.

Use the openssl genrsa command to generate an RSA private key for the private key verification certificate.

openssl genrsa -out verificationCert.key 2048

openssl req -new -key verificationCert.key -out verificationCert.csr

Create a certificate signing request (CSR) file for the private key verification certificate. Enter the registration code that was returned by the aws iot get-registration-code command for the Common Name (CN) field when prompted.

openssl req -new -key verificationCert.key -out verificationCert.csr

Use the openssl x509 command to create a private key verification certificate from the private key CSR file (verificationCert.csr), the CA certificate (myiotCAcert.pem), and the CA certificate private key (myCAprivatekey.key).

openssl x509 -req -in verificationCert.csr -CA myiotCAcert.pem -CAkey myCAprivatekey.key -CAcreateserial -out verificationCert.crt -days 500 -sha256

For more information about the openssl x509 command, see x509.

Register the CA certificate with AWS IoT by passing the CA certificate (myiotCAcert.pem) and the private key verification certificate (verificationCert.crt) to the aws iot register-ca-certificate command. Save the certificate ID value returned when AWS IoT acknowledges registration of the CA certificate.

aws iot register-ca-certificate --ca-certificate file://myiotCAcert.pem --verification-cert file://verificationCert.crt

Note: Pass the certificate ID of an AWS IoT CA certificate to the aws iot describe-ca-certificate command to return the full ARN of the CA certificate. You can also retrieve the full ARN of a CA certificate from the AWS IoT console.

Activate the CA certificate with the aws iot update-ca-certificate command. Specify the certificate ID of the CA certificate for the --certificate-id parameter.

aws iot update-ca-certificate --certificate-id xxxxxxxxxxx --new-status ACTIVE

Note: You can also activate your CA certificate with the aws iot register-ca-certificate command by specifying the --set-as-active parameter. For example, to activate your CA certificate when you register your CA certificate, use the same arguments that you specified in the previous step and append the --set-as-active parameter:

aws iot register-ca-certificate --ca-certificate file://myiotCAcert.pem --verification-cert file://verificationCert.crt --set-as-active

4.    Create, register, and activate a device certificate.

Use the openssl genrsa command to generate a private key.

openssl genrsa -out deviceCert.key 2048

Use the openssl req command to create a CSR file (deviceCert.csr) for the device certificate. You do not need to enter the registration code returned by the aws iot get-registration-code command for the Common Name (CN) when prompted.

openssl req -new -key deviceCert.key -out deviceCert.csr

Use the openssl x509 command to create a device certificate (deviceCert.crt) from the device certificate CSR file (deviceCert.csr), the CA certificate (myiotCAcert.pem), and the CA certificate private key (myCAprivatekey.key).

openssl x509 -req -in deviceCert.csr -CA myiotCAcert.pem -CAkey myCAprivatekey.key -CAcreateserial -out deviceCert.crt -days 500 –sha256

Register the device certificate with AWS IoT by passing the device certificate (deviceCert.crt) and the CA certificate (myiotCAcert.pem) to the aws iot register-certificate command. Save the certificate ID value returned when AWS IoT acknowledges registration of the device certificate.

aws iot register-certificate --certificate-pem file://deviceCert.crt --ca-certificate-pem file://myiotCAcert.pem

Note: Pass the certificate ID of an AWS IoT certificate to the aws iot describe-certificate command to return the full ARN of a certificate that is not a CA certificate. Use the aws iot describe-ca-certificate to return the full ARN of an AWS IoT CA certificate.

Activate the device certificate with the aws iot update-certificate command. Specify the certificate ID of the device certificate for the --certificate-id parameter.

aws iot update-certificate --certificate-id xxxxxxxxxxx --new-status ACTIVE

Note: You can also activate your device certificate with the aws iot register-certificate command by specifying the --set-as-active parameter. For example, to activate your device certificate when you register your device certificate, use the same arguments that you specified in the previous step and append the --set-as-active parameter:

aws iot register-certificate --certificate-pem file://deviceCert.crt --ca-certificate-pem file://myiotCAcert.pem --set-as-active

5.    Create and configure an AWS IoT thing

For this example, use the name 'ruby-test'.

aws iot create-thing --thing-name "ruby-test"

Attach your device certificate to the AWS IoT thing 'ruby-test'. Substitute the device certificate ARN for <CERTIFICATE_ARN>. The device certificate ARN was returned by AWS IoT when the device certificate was registered in step 4.

aws iot attach-thing-principal --thing-name ruby-test --principal <CERTIFICATE_ARN>

Note: Pass the certificate ID of an AWS IoT certificate to the aws iot describe-certificate command to return the full ARN of a device certificate. You can also retrieve the full certificate ARN value from the AWS IoT console.

Create a policy based upon the AWSIoTDataAccess managed policy, which grants full access to AWS IoT messaging actions.

Note: The AWSIoTDataAccess managed policy is highly permissive and should be scoped down to a subset of topics in a real-world scenario.

Create a JSON document that contains the policy information. Save this document as policy.json.

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Effect": "Allow",

            "Action": [

                "iot:Connect",

                "iot:Publish",

                "iot:Subscribe",

                "iot:Receive",

                "iot:GetThingShadow",

                "iot:UpdateThingShadow"'

            ],

            "Resource": "*"

        }

    ]

}

Create the policy IoTDataAccess from policy.json with the aws iot create-policy CLI command:

aws iot create-policy --policy-name IoTDataAccess --policy-document file://policy.json

Attach the new IoTDataAccess policy to the device certificate with the aws iot attach-principal-policy CLI command. Substitute the device certificate ARN for <CERTIFICATE_ARN>. The device certificate ARN was returned by AWS IoT when the device certificate was registered in step 4.

aws iot attach-principal-policy --policy-name IoTDataAccess --principal

5.    Connect to the AWS IoT MQTT endpoint.

Follow these steps to create and run a script that simulates a device connecting to an AWS IoT thing.

Create a file with the following code and save as 'iot-connector.rb'. Update the variables mqtt_url, root_ca, public_crt, and private_key to reference the appropriate MQTT URL and location of your certificates and key.

Note: Run the aws iot describe-endpoint command from the console to determine the value for the mqtt_url variable. If you run this script from the same folder that you created all of your files in, you can simply enclose the name of each of the referenced files in single quotes.

require ‘rubygems’

require ‘mqtt’

 

mqtt_url = ".iot..amazonaws.com"

root_ca = '/path/to/iotRootCA.pem'

public_crt = '/path/to/deviceCert.crt'

private_key = '/path/to/deviceCert.key'

 

puts "Loaded MQTT configuration information."

puts "Endpoint URL: #{mqtt_url}"

puts "Root Cert: #{root_ca}"

puts "Device Cert: #{public_crt}"

puts "Private Key: #{private_key}\n\n"

 

puts "Connecting to AWS IoT Broker..."

 

client = MQTT::Client.connect(

    client_id: 'ruby-mqtt',

    host: mqtt_url,

    port: 8883,

    ssl: :TLSv1_2,

    cert_file: public_crt,

    key_file: private_key,

    ca_file: root_ca

)

 

if client.connected?

    puts "Successfully connected! exiting."

    client.disconnect()

    exit

else

    abort("Error connecting to AWS IoT, exiting.")

end

Run this command from the console to test the code:

ruby iot-connector.rb

7.    Clean up your working directory and any certificates, things, or policies on AWS IoT after testing.

After successfully testing connectivity, you can connect to the AWS IoT console and view the AWS IoT 'ruby-test' thing as well as the certificate, policy, and CA certificate you created. You can delete these objects from the AWS IoT console if you choose.

You can also clean up your working directory now, but if you intend to keep running this example, keep the following files:

iotRootCA.pem - the root CA that is required to authenticate the AWS IoT server

deviceCert.crt - the public key used by the code sample

deviceCert.key - the private key used by the code sample

iot-connector.rb - the ruby code sample

AWS IoT, certificate, self-signing, MQTT, X.509, openssl, crt, iotRootCA.pem, things, ssl, authentication


Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2017-03-03