Azure IoT intermediate - (case 3) device registered to IoT Hub after passing X509 certificate and DPS verification

Case - after the device passes the X509 certificate and is verified by DPS, it registers with IoT Hub and starts to communicate


Steps of this case:

Note that the first two steps have been covered in the previous chapter, and this article begins with step 3.

1. Generate CA Root certificate through openssl and Microsoft sample Powershell script;

2. Upload CA Root certificate to DPS service and complete ownership verification;

3. Generate device certificate through openssl and Microsoft sample Powershll script;

4. The emulator (C) uses the device certificate to authenticate with DPS and register with IoT Hub;

5. The simulator uses the device certificate to send telemetry messages directly to the IoT Hub.


The logic diagram of step 4 / 5 is as follows:


Video Explanation:

You can watch the video explanation in station B:

Or watch it on this website:


Text explanation:

3. Generate device certificate through openssl and Microsoft sample Powershll script;

Execute the following command to generate the device certificate, where mydevice001 represents the certificate name, which is the device ID finally registered in the IoT Hub:

New-CACertsDevice mydevice001



You need to enter the certificate password, which is defined by the user. Here we enter 12345678


Enter the password again as prompted, and the certificate can be generated as shown in the figure below. We use the mydevice001.pfx certificate file in the device.


4. The emulator (C) uses the device certificate to authenticate with DPS and register with IoT Hub;

Copy the certificate into the sample code, which we will talk about in the third chapter Used in Azure IoT intermediate (3) - (case 1) using DPS to register a single device with symmetric key

Download address:

This section uses the azure IOT samples CSharp master \ provisioning \ samples \ device \ x509sample project

Where to modify the code:

”GlobalDeviceEndpoint "changed to" global. Azure devices provisioning. CN "

's'certificatefilename' changed to the name of the certificate, here 'mydevice001.pfx'“

”S "id scope" is changed to the id scope of the actual DPS.

using Microsoft.Azure.Devices.Provisioning.Client;using Microsoft.Azure.Devices.Provisioning.Client.Transport;using Microsoft.Azure.Devices.Shared;using System;using System.IO;using System.Security.Cryptography.X509Certificates;using System.Text;namespace Microsoft.Azure.Devices.Provisioning.Client.Samples{    public static class Program    {        // The Provisioning Hub IDScope.        // For this sample either:        // - pass this value as a command-prompt argument        // - set the DPS_IDSCOPE environment variable 
        // - create a launchSettings.json (see launchSettings.json.template) containing the variable       // private static string s_idScope = Environment.GetEnvironmentVariable("");        private static string s_idScope = "0cn0000DC5D";        // In your Device Provisioning Service please go to "Manage enrollments" and select "Individual Enrollments".        // Select "Add individual enrollment" then fill in the following:        // Mechanism: X.509        // Certificate: 
        //    You can generate a self-signed certificate by running the GenerateTestCertificate.ps1 powershell script.        //    Select the public key 'certificate.cer' file. ('certificate.pfx' contains the private key and is password protected.)        //    For production code, it is advised that you install the certificate in the CurrentUser (My) store.        // DeviceID: iothubx509device1        // X.509 certificates may also be used for enrollment groups.        // In your Device Provisioning Service please go to "Manage enrollments" and select "Enrollment Groups".        // Select "Add enrollment group" then fill in the following:        // Group name: <your  group name>        // Attestation Type: Certificate        // Certificate Type: 
        //    choose CA certificate then link primary and secondary certificates 
        //    OR choose Intermediate certificate and upload primary and secondary certificate files        // You may also change other enrollemtn group parameters according to your needs        private const string GlobalDeviceEndpoint = "";        private static string s_certificateFileName = "mydevice001.pfx";        public static int Main(string[] args)        {            if (string.IsNullOrWhiteSpace(s_idScope) && (args.Length > 0))            {                s_idScope = args[0];            }            if (string.IsNullOrWhiteSpace(s_idScope))            {                Console.WriteLine("ProvisioningDeviceClientX509 <IDScope>");                return 1;            }            X509Certificate2 certificate = LoadProvisioningCertificate();            using (var security = new SecurityProviderX509Certificate(certificate))            // Select one of the available transports:            // To optimize for size, reference only the protocols used by your application.            using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))            // using (var transport = new ProvisioningTransportHandlerHttp())            // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))            // using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly))            {                ProvisioningDeviceClient provClient =                    ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, s_idScope, security, transport);                var sample = new ProvisioningDeviceClientSample(provClient, security);                sample.RunSampleAsync().GetAwaiter().GetResult();            }            return 0;        }        private static X509Certificate2 LoadProvisioningCertificate()        {            string certificatePassword = ReadCertificatePassword();            var certificateCollection = new X509Certificate2Collection();            certificateCollection.Import(s_certificateFileName, certificatePassword, X509KeyStorageFlags.UserKeySet);            X509Certificate2 certificate = null;            foreach (X509Certificate2 element in certificateCollection)            {                Console.WriteLine($"Found certificate: {element?.Thumbprint} {element?.Subject}; PrivateKey: {element?.HasPrivateKey}");                if (certificate == null && element.HasPrivateKey)                {                    certificate = element;                }                else                {                    element.Dispose();                }            }            if (certificate == null)            {                throw new FileNotFoundException($"{s_certificateFileName} did not contain any certificate with a private key.");            }            else            {                Console.WriteLine($"Using certificate {certificate.Thumbprint} {certificate.Subject}");            }            return certificate;        }        private static string ReadCertificatePassword()        {            var password = new StringBuilder();            Console.WriteLine($"Enter the PFX password for {s_certificateFileName}:");            while(true)            {                ConsoleKeyInfo key = Console.ReadKey(true);                if (key.Key == ConsoleKey.Backspace)                {                    if (password.Length > 0)                    {                        password.Remove(password.Length - 1, 1);                        Console.Write("\b \b");                    }                }                else if (key.Key == ConsoleKey.Enter)                {                    Console.WriteLine();                    break;                }                else                {                    Console.Write('*');                    password.Append(key.KeyChar);                }            }            return password.ToString();        }    }}


Before executing the code, add group registration in DPS, select the certificate method, and select the certificate configured to DPS in the previous section from the drop-down list:


Execution code:

Enter the certificate password, and the program returns the name and device ID of the IoT Hub to which the DPS registers the device

At this point, the steps of registering the device with the IoT Hub through the X509 certificate and DPS are completed. You can check the following results in the portal DPS:


At the same time, you can see the following devices in the IoT Hub. The verification method is SelfSigned:


5. The simulator uses the device certificate to send telemetry messages directly to the IoT Hub

Refer to the following documents for this step:

The sample code is as follows:

There are some areas that need to be modified:

44 lines mydevice001.pfx, and 12345678, replace with your certificate path and certificate password;

Line 45, mydevice001, change to your deviceid

In the fourth step, DPS returns IoT Hub


using System;using Microsoft.Azure.Devices.Client;using Microsoft.Azure.Devices.Shared;using System.Security.Cryptography.X509Certificates;using System.Threading.Tasks;using System.Text;namespace x509device{    class Program    {        private static int MESSAGE_COUNT = 5;        private const int TEMPERATURE_THRESHOLD = 30;        private static String deviceId = "mydevice001";        private static float temperature;        private static float humidity;        private static Random rnd = new Random();        static async Task SendEvent(DeviceClient deviceClient)        {            string dataBuffer;            Console.WriteLine("Device sending {0} messages to IoTHub...\n", MESSAGE_COUNT);            for (int count = 0; count < MESSAGE_COUNT; count++)            {                temperature = rnd.Next(20, 35);                humidity = rnd.Next(60, 80);                dataBuffer = string.Format("{{\"deviceId\":\"{0}\",\"messageId\":{1},\"temperature\":{2},\"humidity\":{3}}}", deviceId, count, temperature, humidity);                Message eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer));                eventMessage.Properties.Add("temperatureAlert", (temperature > TEMPERATURE_THRESHOLD) ? "true" : "false");                Console.WriteLine("\t{0}> Sending message: {1}, Data: [{2}]", DateTime.Now.ToLocalTime(), count, dataBuffer);                await deviceClient.SendEventAsync(eventMessage);            }        }        static void Main(string[] args)        {            try            {                var cert = new X509Certificate2("mydevice001.pfx", "12345678");                var auth = new DeviceAuthenticationWithX509Certificate("mydevice001", cert);                var deviceClient = DeviceClient.Create("", auth, TransportType.Amqp_Tcp_Only);                if (deviceClient == null)                {                    Console.WriteLine("Failed to create DeviceClient!");                }                else                {                    Console.WriteLine("Successfully created DeviceClient!");                    SendEvent(deviceClient).Wait();                }                Console.WriteLine("Exiting...\n");            }            catch (Exception ex)            {                Console.WriteLine("Error in sample: {0}", ex.Message);            }        }    }}


Run the program and see that the telemetry results are sent successfully as follows:




Other articles in this series:

  1. (video) Azure IoT intermediate (1) - Device Provisioning Service (DPS) overview

  2. (video) Azure IoT intermediate (2) - understand DPS group registration and separate registration

  3. (video) Azure IoT intermediate (3) - (case 1) use DPS to register a single device with symmetric key

  4. (video) Azure IoT intermediate (4) - (case 2) use DPS to register device group with symmetric key

  5. (video) Azure IoT intermediate (5) - Preparation for using X509 Certificate in DPS/IoT Hub (1) understanding certificate chain

  6. (video) Azure IoT intermediate (6) - preparation to use X509 Certificate in DPS/IoT Hub (2) create self signed certificate and verify ownership

  7. (video) Azure IoT intermediate (7) - (case 3) device passes X509 certificate and is verified by DPS, then register to IoT Hub and start communication


Tags: OpenSSL emulator simulator JSON

Posted on Sat, 07 Mar 2020 17:16:14 -0500 by poelinca