Como conectar dispositivos com certificados X.509 ao IoT Central Application

O IoT Central suporta assinaturas de acesso compartilhado (SAS) e certificados X.509 para proteger a comunicação entre um dispositivo e seu aplicativo. O tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central usa SAS. Neste artigo, você aprenderá a modificar o exemplo de código para usar certificados X.509. Os certificados X.509 são recomendados em ambientes de produção. Para obter mais informações, consulte Conceitos de autenticação de dispositivo.

Este guia mostra duas maneiras de usar certificados X.509: inscrições de grupo normalmente usadas em um ambiente de produção e inscrições individuais úteis para testes. O artigo também descreve como rolar certificados de dispositivo para manter a conectividade quando os certificados expiram.

Este guia baseia-se nos exemplos mostrados no tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central que usa C#, Java, JavaScript e Python. Para obter um exemplo que usa a linguagem de programação C, consulte Provisionar vários dispositivos X.509 usando grupos de registro.

Pré-requisitos

Para concluir as etapas neste guia de instruções, você deve primeiro concluir o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central. Você modifica o código usado no tutorial ao seguir as etapas deste guia.

Neste guia de instruções, você gera alguns certificados X.509 de teste. Para poder gerar esses certificados, você precisa:

  • Uma máquina de desenvolvimento com Node.js versão 6 ou posterior instalada. Você pode executar node --version na linha de comando para verificar sua versão. As instruções neste tutorial pressupõem que você esteja executando o comando node no prompt de comando do Windows. No entanto, você pode usá Node.js em muitos outros sistemas operacionais.
  • Uma cópia local do SDK do Microsoft Azure IoT para Node.js repositório GitHub que contém os scripts para gerar os certificados X.509 de teste. Use este link para baixar uma cópia do repositório: Download ZIP. Em seguida, descompacte o arquivo para um local adequado em sua máquina local.

Usar inscrição em grupo

Use certificados X.509 com um registro de grupo em um ambiente de produção. Em um registro de grupo, você adiciona um certificado X.509 raiz ou intermediário ao seu aplicativo IoT Central. Dispositivos com certificados folha derivados do certificado raiz ou intermediário podem se conectar ao seu aplicativo.

Gerar certificados raiz e de dispositivo

Nesta seção, você usa um certificado X.509 para conectar um dispositivo a um certificado derivado do certificado do grupo de registro do IoT Central.

Aviso

Esta forma de gerar certificados X.509 é apenas para testes. Para um ambiente de produção, você deve usar seu mecanismo oficial e seguro para a geração de certificados.

  1. Navegue até o script do gerador de certificados no SDK do Microsoft Azure IoT para Node.js você baixou. Instale os pacotes necessários:

    cd azure-iot-sdk-node/provisioning/tools
    npm install
    
  2. Crie um certificado raiz e, em seguida, derive um certificado de dispositivo executando o script:

    node create_test_cert.js root mytestrootcert
    node create_test_cert.js device sample-device-01 mytestrootcert
    

    Gorjeta

    Um ID de dispositivo pode conter letras, números e o - caractere.

Esses comandos produzem a seguinte raiz e os certificados de dispositivo:

filename Índice
mytestrootcert_cert.pem A parte pública do certificado X509 raiz
mytestrootcert_key.pem A chave privada para o certificado X509 raiz
mytestrootcert_fullchain.pem O conjunto de chaves para o certificado X509 raiz.
mytestrootcert.pfx O arquivo PFX para o certificado X509 raiz.
sampleDevice01_cert.pem A parte pública do certificado X509 do dispositivo
sampleDevice01_key.pem A chave privada para o certificado X509 do dispositivo
sampleDevice01_fullchain.pem O conjunto de chaves para o certificado X509 do dispositivo.
sampleDevice01.pfx O arquivo PFX para o certificado X509 do dispositivo.

Anote a localização desses arquivos. Você precisa dele mais tarde.

Criar uma inscrição de grupo

  1. Abra seu aplicativo IoT Central e navegue até Permissões no painel esquerdo e selecione Grupos de conexão de dispositivo.

  2. Selecione + Novo para criar um novo grupo de inscrição chamado MyX509Group com um tipo de atestado de Certificados (X.509). Você pode criar grupos de registro para dispositivos IoT ou dispositivos IoT Edge.

  3. No grupo de inscrição que você criou, selecione Gerenciar principal.

  4. No painel Certificado principal, selecione Adicionar certificado.

  5. Carregue o arquivo de certificado raiz chamado mytestrootcert_cert.pem que você gerou anteriormente.

  6. Se você estiver usando uma autoridade de certificação intermediária ou raiz em que confia e sabe que tem propriedade total do certificado, pode atestar automaticamente que verificou o certificado definindo o status do certificado verificado ao carregar para Ativado. Caso contrário, defina o status do certificado verificado ao carregar como Desativado.

  7. Se você definir o status do certificado verificado ao carregar como Desativado, selecione Gerar código de verificação.

  8. Copie o código de verificação, copie-o e crie um certificado de verificação X.509. Por exemplo, no prompt de comando:

    node create_test_cert.js verification --ca mytestrootcert_cert.pem --key mytestrootcert_key.pem --nonce  {verification-code}
    
  9. Selecione Verificar para carregar o certificado de verificação assinado verification_cert.pem para concluir a verificação.

  10. O status do certificado primário agora é Verificado:

    Screenshot that shows a verified X509 certificate.

Agora você pode conectar dispositivos que têm um certificado X.509 derivado desse certificado raiz primária.

Depois de salvar o grupo de inscrição, anote o escopo da ID. Você precisa dele mais tarde.

Executar código de dispositivo de exemplo

Se você estiver usando o Windows, os certificados X.509 devem estar no armazenamento de certificados do Windows para que o exemplo funcione. No Windows Explorer, clique duas vezes nos arquivos PFX gerados anteriormente - mytestrootcert.pfx e sampleDevice01.pfx. No Assistente para Importação de Certificados, selecione Usuário Atual como o local de armazenamento, digite 1234 como senha e deixe o assistente escolher o armazenamento de certificados automaticamente. O assistente importa os certificados para o repositório pessoal do usuário atual.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Na solução IoTHubDeviceSamples Visual Studio, abra o arquivo Parameter.cs no projeto TemperatureController.

  2. Adicione as duas definições de parâmetro a seguir à classe:

    [Option(
        'x',
        "CertificatePath",
        HelpText = "(Required if DeviceSecurityType is \"dps\"). \nThe device PFX file to use during device provisioning." +
        "\nDefaults to environment variable \"IOTHUB_DEVICE_X509_CERT\".")]
    public string CertificatePath { get; set; } = Environment.GetEnvironmentVariable("IOTHUB_DEVICE_X509_CERT");
    
    [Option(
        'p',
        "CertificatePassword",
        HelpText = "(Required if DeviceSecurityType is \"dps\"). \nThe password of the PFX certificate file." +
        "\nDefaults to environment variable \"IOTHUB_DEVICE_X509_PASSWORD\".")]
    public string CertificatePassword { get; set; } = Environment.GetEnvironmentVariable("IOTHUB_DEVICE_X509_PASSWORD");
    

    Guarde as alterações.

  3. Na solução IoTHubDeviceSamples Visual Studio, abra o arquivo Program.cs no projeto TemperatureController.

  4. Adicione as seguintes instruções using:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Adicione o seguinte método à classe :

    private static X509Certificate2 LoadProvisioningCertificate(Parameters parameters)
    {
        var certificateCollection = new X509Certificate2Collection();
        certificateCollection.Import(
            parameters.CertificatePath,
            parameters.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($"{parameters.CertificatePath} did not contain any certificate with a private key.");
        }
    
        Console.WriteLine($"Using certificate {certificate.Thumbprint} {certificate.Subject}");
    
        return certificate;
    }
    
  6. No método, substitua SetupDeviceClientAsync o bloco de código para case "dps" com o seguinte código:

    case "dps":
        s_logger.LogDebug($"Initializing via DPS");
        Console.WriteLine($"Loading the certificate...");
        X509Certificate2 certificate = LoadProvisioningCertificate(parameters);
        DeviceRegistrationResult dpsRegistrationResult = await ProvisionDeviceAsync(parameters, certificate, cancellationToken);
        var authMethod = new DeviceAuthenticationWithX509Certificate(dpsRegistrationResult.DeviceId, certificate);
        deviceClient = InitializeDeviceClient(dpsRegistrationResult.AssignedHub, authMethod);
        break;
    
  7. Substitua o método ProvisionDeviceAsync pelo código abaixo:

    private static async Task<DeviceRegistrationResult> ProvisionDeviceAsync(Parameters parameters, X509Certificate2 certificate, CancellationToken cancellationToken)
    {
        SecurityProvider security = new SecurityProviderX509Certificate(certificate);
        ProvisioningTransportHandler mqttTransportHandler = new ProvisioningTransportHandlerMqtt();
        ProvisioningDeviceClient pdc = ProvisioningDeviceClient.Create(parameters.DpsEndpoint, parameters.DpsIdScope, security, mqttTransportHandler);
    
        var pnpPayload = new ProvisioningRegistrationAdditionalData
        {
            JsonData = PnpConvention.CreateDpsPayload(ModelId),
        };
        return await pdc.RegisterAsync(pnpPayload, cancellationToken);
    }
    

    Guarde as alterações.

Para executar o exemplo:

  1. Adicione as seguintes variáveis de ambiente ao projeto:

    • IOTHUB_DEVICE_X509_CERT: <full path to folder that contains PFX files>sampleDevice01.pfx
    • IOTHUB_DEVICE_X509_PASSWORD: 1234.
  2. Compile e execute a aplicação. Verifique se as provisões do dispositivo foram bem-sucedidas.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample que contém o arquivo pom.xml e a pasta src para o exemplo de dispositivo controlador de temperatura.

  2. Edite o arquivo pom.xml para adicionar a seguinte configuração de dependência no <dependencies> nó:

    <dependency>
        <groupId>com.microsoft.azure.sdk.iot.provisioning.security</groupId>
        <artifactId>${x509-provider-artifact-id}</artifactId>
        <version>${x509-provider-version}</version>
    </dependency>
    

    Guarde as alterações.

  3. Abra o arquivo src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java no editor de texto.

  4. Substitua a SecurityProviderSymmetricKey importação pelas seguintes importações:

    import com.microsoft.azure.sdk.iot.provisioning.security.SecurityProvider;
    import com.microsoft.azure.sdk.iot.provisioning.security.hsm.SecurityProviderX509Cert;
    import com.microsoft.azure.sdk.iot.provisioning.security.exceptions.SecurityProviderException;
    
  5. Adicione a seguinte importação:

    import java.nio.file.*;
    
  6. Adicione SecurityProviderException à lista de exceções que o main método lança:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Substitua o método initializeAndProvisionDevice pelo código abaixo:

    private static void initializeAndProvisionDevice() throws ProvisioningDeviceClientException, IOException, URISyntaxException, InterruptedException, SecurityProviderException {
        String deviceX509Key = new String(Files.readAllBytes(Paths.get(System.getenv("IOTHUB_DEVICE_X509_KEY"))));
        String deviceX509Cert = new String(Files.readAllBytes(Paths.get(System.getenv("IOTHUB_DEVICE_X509_CERT"))));
        SecurityProvider securityProviderX509 = new SecurityProviderX509Cert(deviceX509Cert, deviceX509Key, null);
        ProvisioningDeviceClient provisioningDeviceClient;
        ProvisioningStatus provisioningStatus = new ProvisioningStatus();
    
        provisioningDeviceClient = ProvisioningDeviceClient.create(globalEndpoint, scopeId, provisioningProtocol, securityProviderX509);
    
        AdditionalData additionalData = new AdditionalData();
        additionalData.setProvisioningPayload(com.microsoft.azure.sdk.iot.provisioning.device.plugandplay.PnpHelper.createDpsPayload(MODEL_ID));
    
        provisioningDeviceClient.registerDevice(new ProvisioningDeviceClientRegistrationCallbackImpl(), provisioningStatus, additionalData);
    
        while (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() != ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED)
        {
            if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ERROR ||
                    provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_DISABLED ||
                    provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_FAILED)
            {
                provisioningStatus.exception.printStackTrace();
                System.out.println("Registration error, bailing out");
                break;
            }
            System.out.println("Waiting for Provisioning Service to register");
            Thread.sleep(MAX_TIME_TO_WAIT_FOR_REGISTRATION);
        }
    
        ClientOptions options = new ClientOptions();
        options.setModelId(MODEL_ID);
    
        if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
            System.out.println("IotHUb Uri : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri());
            System.out.println("Device ID : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId());
    
            String iotHubUri = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri();
            String deviceId = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId();
    
            log.debug("Opening the device client.");
            deviceClient = DeviceClient.createFromSecurityProvider(iotHubUri, deviceId, securityProviderX509, IotHubClientProtocol.MQTT, options);
            deviceClient.open();
        }
    }
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>sampleDevice01_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>sampleDevice01_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Compile e execute a aplicação. Verifique se as provisões do dispositivo foram bem-sucedidas.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-sdk-node/device/samples/javascript que contém o aplicativo pnp_temperature_controller.js e execute o seguinte comando para instalar o pacote X.509:

    npm install azure-iot-security-x509 --save
    
  2. Abra o arquivo pnp_temperature_controller.js em um editor de texto.

  3. Edite as require instruções para incluir o seguinte código:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Adicione as quatro linhas a seguir à seção "Informações de conexão DPS" para inicializar a deviceCert variável:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Edite a provisionDevice função que cria o cliente substituindo a primeira linha pelo seguinte código:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. Na mesma função, modifique a linha que define a deviceConnectionString variável da seguinte maneira:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main Na função, adicione a seguinte linha após a linha que chama Client.fromConnectionString:

    client.setOptions(deviceCert);
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>sampleDevice01_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>sampleDevice01_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Execute o script e verifique se as provisões do dispositivo foram bem-sucedidas:

    node pnp_temperature_controller.js
    

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-device/samples/pnp e abra o arquivo temp_controller_with_thermostats.py em um editor de texto.

  2. Adicione a seguinte from instrução para importar a funcionalidade X.509:

    from azure.iot.device import X509
    
  3. Modifique a primeira parte da provision_device função da seguinte maneira:

    async def provision_device(provisioning_host, id_scope, registration_id, x509, model_id):
        provisioning_device_client = ProvisioningDeviceClient.create_from_x509_certificate(
            provisioning_host=provisioning_host,
            registration_id=registration_id,
            id_scope=id_scope,
            x509=x509,
        )
    
  4. main Na função, substitua a linha que define a symmetric_key variável pelo seguinte código:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. main Na função, substitua a chamada para a provision_device função com o seguinte código:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. main Na função, substitua a chamada para a IoTHubDeviceClient.create_from_symmetric_key função com o seguinte código:

    device_client = IoTHubDeviceClient.create_from_x509_certificate(
        x509=x509,
        hostname=registration_result.registration_state.assigned_hub,
        device_id=registration_result.registration_state.device_id,
        product_info=model_id,
    )
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>sampleDevice01_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>sampleDevice01_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Execute o script e verifique se as provisões do dispositivo foram bem-sucedidas:

    python temp_controller_with_thermostats.py
    

Verifique se a telemetria aparece na visualização do dispositivo em seu aplicativo IoT Central:

Screenshot showing telemetry from a device that connected using X.509.

Usar inscrição individual

Use certificados X.509 com um registro individual para testar seu dispositivo e solução. Em um registro individual, não há nenhum certificado X.509 raiz ou intermediário em seu aplicativo IoT Central. Os dispositivos usam um certificado X.509 autoassinado para se conectar ao seu aplicativo.

Gerar certificado de dispositivo autoassinado

Nesta seção, você usa um certificado X.509 autoassinado para conectar dispositivos para registro individual, que são usados para registrar um único dispositivo. Os certificados autoassinados são apenas para teste.

Aviso

Esta forma de gerar certificados X.509 é apenas para testes. Para um ambiente de produção, você deve usar seu mecanismo oficial e seguro para a geração de certificados.

Crie um certificado de dispositivo X.509 autoassinado executando os seguintes comandos:

  cd azure-iot-sdk-node/provisioning/tools
  node create_test_cert.js device mytestselfcertprimary
  node create_test_cert.js device mytestselfcertsecondary 

Gorjeta

Um ID de dispositivo pode conter letras, números e o - caractere.

Esses comandos produzem os seguintes certificados de dispositivo:

filename Índice
mytestselfcertprimary_cert.pem A parte pública do certificado X509 do dispositivo principal
mytestselfcertprimary_key.pem A chave privada para o certificado X509 do dispositivo primário
mytestselfcertprimary_fullchain.pem O conjunto de chaves para o certificado X509 do dispositivo principal.
mytestselfcertprimary.pfx O arquivo PFX para o certificado X509 do dispositivo primário.
mytestselfcertsecondary_cert.pem A parte pública do certificado X509 do dispositivo secundário
mytestselfcertsecondary_key.pem A chave privada para o certificado X509 do dispositivo secundário
mytestselfcertsecondary_fullchain.pem O conjunto de chaves para o certificado X509 do dispositivo secundário.
mytestselfcertsecondary.pfx O arquivo PFX para o certificado X509 do dispositivo secundário.

Criar inscrição individual

  1. No aplicativo Azure IoT Central, selecione Dispositivos e crie um novo dispositivo com a ID do Dispositivo como mytestselfcertprimary a partir do modelo de dispositivo termostato. Anote o escopo do ID e use-o mais tarde.

  2. Abra o dispositivo que criou e selecione Ligar.

  3. Selecione Inscrição individual como o tipo de autenticação e Certificados (X.509) como o método de autenticação.

  4. Carregue o arquivo mytestselfcertprimary_cert.pem que você gerou anteriormente como o certificado primário.

  5. Carregue o arquivo mytestselfcertsecondary_cert.pem que você gerou anteriormente como o certificado secundário. Em seguida, selecione Guardar.

  6. O dispositivo agora tem um registro individual com certificados X.509.

    Screenshot that shows how to connect a device using an X.509 individual enrollment.

Executar um exemplo de dispositivo de registro individual

Se você estiver usando o Windows, os certificados X.509 devem estar no armazenamento de certificados do Windows para que o exemplo funcione. No Windows Explorer, clique duas vezes nos arquivos PFX gerados anteriormente - mytestselfcertprimary.pfx e mytestselfcertsecondary.pfx. No Assistente para Importação de Certificados, selecione Usuário Atual como o local de armazenamento, digite 1234 como senha e deixe o assistente escolher o armazenamento de certificados automaticamente. O assistente importa os certificados para o repositório pessoal do usuário atual.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Na solução IoTHubDeviceSamples Visual Studio, abra o arquivo Parameter.cs no projeto TemperatureController.

  2. Adicione as duas definições de parâmetro a seguir à classe:

    [Option(
        'x',
        "CertificatePath",
        HelpText = "(Required if DeviceSecurityType is \"dps\"). \nThe device PFX file to use during device provisioning." +
        "\nDefaults to environment variable \"IOTHUB_DEVICE_X509_CERT\".")]
    public string CertificatePath { get; set; } = Environment.GetEnvironmentVariable("IOTHUB_DEVICE_X509_CERT");
    
    [Option(
        'p',
        "CertificatePassword",
        HelpText = "(Required if DeviceSecurityType is \"dps\"). \nThe password of the PFX certificate file." +
        "\nDefaults to environment variable \"IOTHUB_DEVICE_X509_PASSWORD\".")]
    public string CertificatePassword { get; set; } = Environment.GetEnvironmentVariable("IOTHUB_DEVICE_X509_PASSWORD");
    

    Guarde as alterações.

  3. Na solução IoTHubDeviceSamples Visual Studio, abra o arquivo Program.cs no projeto TemperatureController.

  4. Adicione as seguintes instruções using:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Adicione o seguinte método à classe :

    private static X509Certificate2 LoadProvisioningCertificate(Parameters parameters)
    {
        var certificateCollection = new X509Certificate2Collection();
        certificateCollection.Import(
            parameters.CertificatePath,
            parameters.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($"{parameters.CertificatePath} did not contain any certificate with a private key.");
        }
    
        Console.WriteLine($"Using certificate {certificate.Thumbprint} {certificate.Subject}");
    
        return certificate;
    }
    
  6. No método, substitua SetupDeviceClientAsync o bloco de código para case "dps" com o seguinte código:

    case "dps":
        s_logger.LogDebug($"Initializing via DPS");
        Console.WriteLine($"Loading the certificate...");
        X509Certificate2 certificate = LoadProvisioningCertificate(parameters);
        DeviceRegistrationResult dpsRegistrationResult = await ProvisionDeviceAsync(parameters, certificate, cancellationToken);
        var authMethod = new DeviceAuthenticationWithX509Certificate(dpsRegistrationResult.DeviceId, certificate);
        deviceClient = InitializeDeviceClient(dpsRegistrationResult.AssignedHub, authMethod);
        break;
    
  7. Substitua o método ProvisionDeviceAsync pelo código abaixo:

    private static async Task<DeviceRegistrationResult> ProvisionDeviceAsync(Parameters parameters, X509Certificate2 certificate, CancellationToken cancellationToken)
    {
        SecurityProvider security = new SecurityProviderX509Certificate(certificate);
        ProvisioningTransportHandler mqttTransportHandler = new ProvisioningTransportHandlerMqtt();
        ProvisioningDeviceClient pdc = ProvisioningDeviceClient.Create(parameters.DpsEndpoint, parameters.DpsIdScope, security, mqttTransportHandler);
    
        var pnpPayload = new ProvisioningRegistrationAdditionalData
        {
            JsonData = PnpConvention.CreateDpsPayload(ModelId),
        };
        return await pdc.RegisterAsync(pnpPayload, cancellationToken);
    }
    

    Guarde as alterações.

Para executar o exemplo:

  1. Adicione as seguintes variáveis de ambiente ao projeto:

    • IOTHUB_DEVICE_DPS_DEVICE_ID: mytestselfcertprimary
    • IOTHUB_DEVICE_X509_CERT: <full path to folder that contains PFX files>mytestselfcertprimary.pfx
    • IOTHUB_DEVICE_X509_PASSWORD: 1234.
  2. Compile e execute a aplicação. Verifique se as provisões do dispositivo foram bem-sucedidas.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample que contém o arquivo pom.xml e a pasta src para o exemplo de dispositivo controlador de temperatura.

  2. Edite o arquivo pom.xml para adicionar a seguinte configuração de dependência no <dependencies> nó:

    <dependency>
        <groupId>com.microsoft.azure.sdk.iot.provisioning.security</groupId>
        <artifactId>${x509-provider-artifact-id}</artifactId>
        <version>${x509-provider-version}</version>
    </dependency>
    

    Guarde as alterações.

  3. Abra o arquivo src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java no editor de texto.

  4. Substitua a SecurityProviderSymmetricKey importação pelas seguintes importações:

    import com.microsoft.azure.sdk.iot.provisioning.security.SecurityProvider;
    import com.microsoft.azure.sdk.iot.provisioning.security.hsm.SecurityProviderX509Cert;
    import com.microsoft.azure.sdk.iot.provisioning.security.exceptions.SecurityProviderException;
    
  5. Adicione a seguinte importação:

    import java.nio.file.*;
    
  6. Adicione SecurityProviderException à lista de exceções que o main método lança:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Substitua o método initializeAndProvisionDevice pelo código abaixo:

    private static void initializeAndProvisionDevice() throws ProvisioningDeviceClientException, IOException, URISyntaxException, InterruptedException, SecurityProviderException {
        String deviceX509Key = new String(Files.readAllBytes(Paths.get(System.getenv("IOTHUB_DEVICE_X509_KEY"))));
        String deviceX509Cert = new String(Files.readAllBytes(Paths.get(System.getenv("IOTHUB_DEVICE_X509_CERT"))));
        SecurityProvider securityProviderX509 = new SecurityProviderX509Cert(deviceX509Cert, deviceX509Key, null);
        ProvisioningDeviceClient provisioningDeviceClient;
        ProvisioningStatus provisioningStatus = new ProvisioningStatus();
    
        provisioningDeviceClient = ProvisioningDeviceClient.create(globalEndpoint, scopeId, provisioningProtocol, securityProviderX509);
    
        AdditionalData additionalData = new AdditionalData();
        additionalData.setProvisioningPayload(com.microsoft.azure.sdk.iot.provisioning.device.plugandplay.PnpHelper.createDpsPayload(MODEL_ID));
    
        provisioningDeviceClient.registerDevice(new ProvisioningDeviceClientRegistrationCallbackImpl(), provisioningStatus, additionalData);
    
        while (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() != ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED)
        {
            if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ERROR ||
                    provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_DISABLED ||
                    provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_FAILED)
            {
                provisioningStatus.exception.printStackTrace();
                System.out.println("Registration error, bailing out");
                break;
            }
            System.out.println("Waiting for Provisioning Service to register");
            Thread.sleep(MAX_TIME_TO_WAIT_FOR_REGISTRATION);
        }
    
        ClientOptions options = new ClientOptions();
        options.setModelId(MODEL_ID);
    
        if (provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getProvisioningDeviceClientStatus() == ProvisioningDeviceClientStatus.PROVISIONING_DEVICE_STATUS_ASSIGNED) {
            System.out.println("IotHUb Uri : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri());
            System.out.println("Device ID : " + provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId());
    
            String iotHubUri = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getIothubUri();
            String deviceId = provisioningStatus.provisioningDeviceClientRegistrationInfoClient.getDeviceId();
    
            log.debug("Opening the device client.");
            deviceClient = DeviceClient.createFromSecurityProvider(iotHubUri, deviceId, securityProviderX509, IotHubClientProtocol.MQTT, options);
            deviceClient.open();
        }
    }
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_DPS_DEVICE_ID=mytestselfcertprimary
    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>mytestselfcertprimary_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>mytestselfcertprimary_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Compile e execute a aplicação. Verifique se as provisões do dispositivo foram bem-sucedidas.

Você também pode repetir as etapas acima para mytestselfcertsecondary certificate.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-sdk-node/device/samples/javascript que contém o aplicativo pnp_temperature_controller.js e execute o seguinte comando para instalar o pacote X.509:

    npm install azure-iot-security-x509 --save
    
  2. Abra o arquivo pnp_temperature_controller.js em um editor de texto.

  3. Edite as require instruções para incluir o seguinte código:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Adicione as quatro linhas a seguir à seção "Informações de conexão DPS" para inicializar a deviceCert variável:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Edite a provisionDevice função que cria o cliente substituindo a primeira linha pelo seguinte código:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. Na mesma função, modifique a linha que define a deviceConnectionString variável da seguinte maneira:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main Na função, adicione a seguinte linha após a linha que chama Client.fromConnectionString:

    client.setOptions(deviceCert);
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_DPS_DEVICE_ID=mytestselfcertprimary
    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>mytestselfcertprimary_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>mytestselfcertprimary_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Execute o script e verifique se as provisões do dispositivo foram bem-sucedidas:

    node pnp_temperature_controller.js
    

Você também pode repetir as etapas acima para mytestselfcertsecondary certificate.

Para modificar o código de exemplo para usar os certificados X.509:

  1. Navegue até a pasta azure-iot-device/samples/pnp e abra o arquivo temp_controller_with_thermostats.py em um editor de texto.

  2. Adicione a seguinte from instrução para importar a funcionalidade X.509:

    from azure.iot.device import X509
    
  3. Modifique a primeira parte da provision_device função da seguinte maneira:

    async def provision_device(provisioning_host, id_scope, registration_id, x509, model_id):
        provisioning_device_client = ProvisioningDeviceClient.create_from_x509_certificate(
            provisioning_host=provisioning_host,
            registration_id=registration_id,
            id_scope=id_scope,
            x509=x509,
        )
    
  4. main Na função, substitua a linha que define a symmetric_key variável pelo seguinte código:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. main Na função, substitua a chamada para a provision_device função com o seguinte código:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. main Na função, substitua a chamada para a IoTHubDeviceClient.create_from_symmetric_key função com o seguinte código:

    device_client = IoTHubDeviceClient.create_from_x509_certificate(
        x509=x509,
        hostname=registration_result.registration_state.assigned_hub,
        device_id=registration_result.registration_state.device_id,
        product_info=model_id,
    )
    

    Guarde as alterações.

Para executar o exemplo:

  1. Em seu ambiente de shell, adicione as duas variáveis de ambiente a seguir. Certifique-se de fornecer o caminho completo para os arquivos PEM e usar o delimitador de caminho correto para seu sistema operacional:

    set IOTHUB_DEVICE_DPS_DEVICE_ID=mytestselfcertprimary
    set IOTHUB_DEVICE_X509_CERT=<full path to folder that contains PEM files>mytestselfcertprimary_cert.pem
    set IOTHUB_DEVICE_X509_KEY=<full path to folder that contains PEM files>mytestselfcertprimary_key.pem
    

    Gorjeta

    Você define as outras variáveis de ambiente necessárias quando concluiu o tutorial Criar e conectar um aplicativo cliente ao seu aplicativo do Azure IoT Central.

  2. Execute o script e verifique se as provisões do dispositivo foram bem-sucedidas:

    python temp_controller_with_thermostats.py
    

Você também pode repetir as etapas acima para mytestselfcertsecondary certificate.

Ligar um dispositivo do IoT Edge

Esta seção pressupõe que você esteja usando um registro de grupo para conectar seu dispositivo IoT Edge. Siga as etapas nas seções anteriores para:

Para conectar o dispositivo IoT Edge ao IoT Central usando o certificado de dispositivo X.509:

  • Copie o certificado do dispositivo e os arquivos de chave para o dispositivo IoT Edge. No exemplo de inscrição de grupo anterior, esses arquivos eram chamados de sampleDevice01_key.pem e sampleDevice01_cert.pem.

  • No dispositivo IoT Edge, edite provisioning a seção no arquivo de configuração /etc/aziot/config.toml da seguinte maneira:

    # DPS X.509 provisioning configuration
    provisioning:
      source: "dps"
      global_endpoint: "https://global.azure-devices-provisioning.net"
      scope_id: "<SCOPE_ID>"
      attestation:
        method: "x509"
    #   registration_id: "<OPTIONAL REGISTRATION ID. LEAVE COMMENTED OUT TO REGISTER WITH CN OF identity_cert>"
        identity_cert: "file:///<path>/sampleDevice01_cert.pem"
        identity_pk: "file:///<path>/sampleDevice01_key.pem"
    #  always_reprovision_on_startup: true
    #  dynamic_reprovisioning: false
    
    [provisioning]
    source = "dps"
    global_endpoint = "https://global.azure-devices-provisioning.net"
    id_scope = "<SCOPE_ID>"
    
    [provisioning.attestation]
    method = "x509"
    registration_id = "env-sens-001"
    identity_pk = "file:///<path>/envSens001_key.pem"
    identity_cert = "file:///<path>/envSens001_cert.pem"
    

    Gorjeta

    Você não precisa adicionar um valor para o registration_id. O IoT Edge pode usar o valor CN do certificado X.509.

  • Execute o seguinte comando para reiniciar o tempo de execução do IoT Edge:

    sudo iotedge config apply
    

Para saber mais, consulte Criar e provisionar dispositivos IoT Edge em escala no Linux usando certificados X.509.

Conectar um dispositivo downstream ao IoT Edge

O IoT Edge usa certificados X.509 para proteger a conexão entre dispositivos downstream e um dispositivo IoT Edge que atua como um gateway transparente. Para saber mais sobre como configurar esse cenário, consulte Conectar um dispositivo downstream a um gateway do Azure IoT Edge.

Rolar seus certificados de dispositivo X.509

Durante o ciclo de vida do seu aplicativo IoT Central, talvez seja necessário rolar seus certificados X.509. Por exemplo:

  • Se você tiver uma violação de segurança, a transferência de certificados é uma prática recomendada de segurança para ajudar a proteger seu sistema.
  • Os certificados X.509 têm datas de validade. A frequência com que você rola seus certificados depende das necessidades de segurança da sua solução. Os clientes com soluções que envolvem dados altamente confidenciais podem rolar certificados diariamente, enquanto outros rolam seus certificados a cada dois anos.

Para conectividade ininterrupta, o IoT Central permite configurar certificados X.509 primários e secundários. Se os certificados primário e secundário tiverem datas de expiração diferentes, você poderá rolar o certificado expirado enquanto os dispositivos continuarem a se conectar ao outro certificado.

Para saber mais, consulte Assumir metodologia de violação.

Esta seção descreve como rolar os certificados no IoT Central. Ao rolar um certificado no IoT Central, você também precisa copiar o novo certificado de dispositivo para seus dispositivos.

Obter novos certificados X.509

Obtenha novos certificados X.509 do seu provedor de certificados. Você pode criar seus próprios certificados X.509 usando uma ferramenta como OpenSSL. Essa abordagem é útil para testar certificados X.509, mas fornece poucas garantias de segurança. Use essa abordagem apenas para testes, a menos que você esteja preparado para agir como seu próprio provedor de autoridade de certificação.

Grupos de inscrição e violações de segurança

Para atualizar um registro de grupo em resposta a uma violação de segurança, você deve usar a seguinte abordagem para atualizar o certificado atual imediatamente. Conclua estas etapas para os certificados primário e secundário se ambos estiverem comprometidos:

  1. Navegue até Permissões no painel esquerdo e selecione Grupos de conexão de dispositivo.

  2. Selecione o nome do grupo na lista em Grupos de inscrição.

  3. Para atualização de certificado, selecione Gerenciar primário ou Gerenciar secundário.

  4. Adicione e verifique o certificado raiz X.509 no grupo de inscrição.

Inscrições individuais e violações de segurança

Se você estiver rolando certificados em resposta a uma violação de segurança, use a abordagem a seguir para atualizar o certificado atual imediatamente. Conclua estas etapas para os certificados primário e secundário, se ambos estiverem comprometidos:

  1. Selecione Dispositivos e selecione o dispositivo.

  2. Selecione Connect e selecione connect method como Inscrição individual

  3. Selecione Certificados (X.509) como mecanismo.

  4. Para atualização de certificado, selecione o ícone de pasta para selecionar o novo certificado a ser carregado para a entrada de inscrição. Selecione Guardar.

Grupos de inscrição e expiração de certificados

Para lidar com expirações de certificado, use a seguinte abordagem para atualizar o certificado atual imediatamente:

  1. Navegue até Permissões no painel esquerdo e selecione Grupos de conexão de dispositivo.

  2. Selecione o nome do grupo na lista em Grupos de inscrição.

  3. Para atualização de certificado, selecione Gerenciar principal.

  4. Adicione e verifique o certificado raiz X.509 no grupo de inscrição.

  5. Mais tarde, quando o certificado secundário expirar, volte e atualize o certificado secundário.

Inscrições individuais e expiração do certificado

Se você estiver rolando certificados para lidar com expirações de certificados, deverá usar a configuração de certificado secundário da seguinte forma para reduzir o tempo de inatividade dos dispositivos que tentam provisionar em seu aplicativo.

Quando o certificado secundário se aproxima da expiração e precisa ser rolado, você pode alternar para usar a configuração primária. Alternar entre os certificados primário e secundário dessa forma reduz o tempo de inatividade dos dispositivos que tentam provisionar em seu aplicativo.

  1. Selecione Dispositivos e selecione o dispositivo.

  2. Selecione Connect e selecione connect method como Inscrição individual

  3. Selecione Certificados (X.509) como mecanismo.

  4. Para atualização de certificado secundário, selecione o ícone de pasta para selecionar o novo certificado a ser carregado para a entrada de inscrição. Selecione Guardar.

  5. Mais tarde, quando o certificado primário expirar, volte e atualize o certificado primário.