Registering a device on Azure IoT-hub programatically using mqtt

1.2k Views Asked by At

Is there anyway to register the new device onto the azure iot-hub programmatically using the self/CA created certificates?

For example say, I want to register my raspberry pi on to my newly created IOT-HUB from the same rasp pi. I know we can do it using the AZ Cli. What I am looking for is there a way to do it programmatically, using MQTT/REST?.

Thanks in advance.

Regards, Pradeep

3

There are 3 best solutions below

2
On

You can make use of the device provisioning service - DPS. The DPS is another service whose purpose is to identify your device, and in case that the device identification is recognized by the DPS, the DPS will create an identity in your IoT Hub.

You set the DPS in a way that you create either individual enrollment(for individual device onboarding) or a group enrollment(for a group of the devices, typically if you use certificates or shared access key authentication type). Enrollments typically contain an identification type that the device should present, and IoT Hub to which the device with the presented identification should be assigned.

The typical flow is that the device reaches out to the DPS with some public identification(certificate chain, TPM registration id, or SAS key). Then internally, the DPS can challenge the device(proof-of-possesion in case of CA certificates), and if the device successfully solves the challenge, that means that the device contains a specific secret(private key in case of CA certs) that identifies that device, so the DPS will create the device identity to the assigned hub in that specific enrollment. This process is called attestation.

As a result, on the device side, you receive at least the IoT Hub endpoint, and the device Id which you use to communicate with the IoT Hub.

Below are the code snippets of how you can do this with CA certificates and C#:

var certificate = new X509Certificate2(leafCertificatePath, leafCertificatePassword);
    using (var security = new SecurityProviderX509Certificate(certificate))
    using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
    {
        ProvisioningDeviceClient provClient =
        ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, dpsScope, security, transport);
    
        var deviceAuthentication = await GetDeviceRegistrationResultAsync(provClient, security);
    
        var auth = new DeviceAuthenticationWithX509Certificate(deviceAuthentication.DeviceId, security.GetAuthenticationCertificate());
    
        var deviceClient = DeviceClient.Create(hostname: deviceAuthentication.AssignedHub,
                                               authenticationMethod: auth,
                                               transportType: TransportType.Mqtt);
    
    
        if (deviceClient == null)
        {
            Console.WriteLine("Failed to create DeviceClient!");
        }
        else
        {
            SendEvents(deviceClient, MESSAGE_COUNT).Wait();
        }
    }

Method for getting the device registration result from the DPS:

static async Task<DeviceRegistrationResult> GetDeviceRegistrationResultAsync(ProvisioningDeviceClient provClient, SecurityProviderX509 security)
{
    DeviceRegistrationResult result = await provClient.RegisterAsync().ConfigureAwait(false);

    if (result.Status != ProvisioningRegistrationStatusType.Assigned)
    {
        throw new Exception("Device not assigned");
    }
    return result;
}

Official example from MSFT you can find here

Here is how you can create and verify certificates with IoT Hub and DPS.

1
On

Just to clarify, 'registering' a device in IoTHub/DPS is kind of an overloaded term, and may mean different things to different people. If you are using self-signed certs, it's a two step process.

First, you need to enroll the device in DPS, which lets DPS know that sometime in the future, a device may show up with that name and that certificate. That is generally a backend process typically NOT done from the device itself. Technically, there's nothing stopping you from calling the REST APIs to do so from the device, but since you need some pretty powerful credentials to do so, it's not recommended to have them on your device. This cannot be done over MQTT. You can avoid having to enroll every individual device by uploading, verifying, and using a CA-signed cert, though.

Once that's done, the device can now/later register itself, which is the act of actually having DPS create the device registration record in IoT Hub. The device "phones home" to DPS, authenticates itself using the cert you provided in the enrollment, and registers itself, getting the IoT Hub connection information it needs back from DPS. That process can be done over MQTT and you can find step by step the process on my blog -> http://busbyland.com/azure-device-provisioning-server-over-mqtt-using-x509-certificates

1
On

Provisioning a device in IoTHub from the device itself is not recommended, as it will then require IoTHub registry write permission and use of service SDK.

The recommended approach is to use Device Provisioning Service, you can create individual or group enrollment with X509 and it will automatically provision the device in target IoTHub.

The device just needs

  1. mechanism to attest its identity
  2. DPS global endpoint
  3. ID Scope to identify your instance of DPS.

Check this - https://learn.microsoft.com/en-us/azure/iot-dps/concepts-x509-attestation