Compartilhar via


Como conectar dispositivos com certificados X.509 a um aplicativo do Azure IoT Central

O IoT Central dá suporte para SAS (assinaturas de acesso compartilhado) e para certificados X.509 para proteger a comunicação entre um dispositivo e o 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 para ambientes de produção. Para saber mais, confira Conceitos de autenticação de dispositivo.

Este artigo mostra duas maneiras de usar o X.509: com os registros de grupo, que normalmente são usados em um ambiente de produção; e com os registros individuais, que são úteis para teste. O artigo também descreve como distribuir certificados de dispositivo para manter a conectividade quando os certificados expiram.

Este guia se baseia nos exemplos mostrados no tutorial Criar e conectar um aplicativo cliente ao seu aplicativo 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, primeiro você deve 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ê vai gerar alguns certificados X.509 de teste. Para gerar esses certificados, você precisará de:

  • Um computador de desenvolvimento com o Node.js versão 6 ou posterior instalado. É possível executar node --version na linha de comando para verificar a versão. As instruções deste tutorial pressupõem que você esteja executando o comando node no prompt de comando do Windows. Contudo, você pode usar o Node.js em muitos outros sistemas operacionais.
  • Uma cópia local do repositório do GitHub do SDK do Microsoft Azure IoT para Node.js que contenha os scripts para gerar os certificados X.509 de teste. Use este link para baixar uma cópia do repositório: Baixar ZIP. Em seguida, descompacte o arquivo em uma localização adequada no computador local.

Usar o registro de grupo

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

Gerar certificados de dispositivo e de raiz

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

Aviso

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

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

    cd azure-iot-sdk-node/provisioning/tools
    npm install
    
  2. Crie um certificado raiz e 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
    

    Dica

    Uma identificação do dispositivo pode conter letras, números e o caractere -.

Esses comandos produzem os seguintes certificados raiz e de dispositivo:

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

Anote o local desses arquivos. Isso será necessário mais tarde.

Criar um registro de grupo

  1. Abra o aplicativo do 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 registro chamado MyX509Group com um tipo de atestado de Certificados (X.509). Crie grupos de registro para dispositivos IoT ou dispositivos IoT Edge.

  3. No grupo de registro que você criou, selecione Gerenciar primário.

  4. No painel de Certificado primário, selecione Adicionar certificado.

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

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

  7. Se você definir o status do certificado verificado no upload para 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ário.

Depois de salvar o grupo de registro, anote o escopo da ID. Isso será necessário mais tarde.

Executar o código do dispositivo de amostra

Se estiver usando Windows, os certificados X.509 deverão estar no repositório 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, insira 1234 como a senha e deixe o assistente escolher o repositório de certificados automaticamente. O assistente importa os certificados para o repositório pessoal do usuário atual.

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

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

  2. Adicione as duas definições seguintes de parâmetro para a 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");
    

    Salve as alterações.

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

  4. Adicione as seguintes declarações de 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 SetupDeviceClientAsync, substitua o bloco de códigos por 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 seguinte código:

    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);
    }
    

    Salve 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 o aplicativo. Verifique se o dispositivo foi provisionado com êxito.

Para modificar o código de exemplo a fim de 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 até a pasta src com o arquivo de exemplo do controlador de temperatura.

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

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

    Salve as alterações.

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

  4. Substitua a importação SecurityProviderSymmetricKey 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 importação a seguir:

    import java.nio.file.*;
    
  6. Adicione SecurityProviderException à lista de exceções geradas pelo método main:

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

    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();
        }
    }
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Compile e execute o aplicativo. Verifique se o dispositivo foi provisionado com êxito.

Para modificar o código de exemplo a fim de 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 instruções require para incluir o seguinte:

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

    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 função provisionDevice que cria o cliente substituindo a primeira linha pelo código seguinte:

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

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

    client.setOptions(deviceCert);
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Execute o script e verifique se o dispositivo foi provisionado com êxito:

    node pnp_temperature_controller.js
    

Para modificar o código de exemplo a fim de 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 instrução from para importar a funcionalidade X.509:

    from azure.iot.device import X509
    
  3. Modifique a primeira parte da função provision_device 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. Na função main, substitua a linha que define a variável symmetric_key com o seguinte código:

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

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. Na função main, substitua a chamada para a função IoTHubDeviceClient.create_from_symmetric_key pelo 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,
    )
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Execute o script e verifique se o dispositivo foi provisionado com êxito:

    python temp_controller_with_thermostats.py
    

Verifique se a telemetria aparece no modo de exibição de dispositivo em seu aplicativo no IoT Central:

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

Usar registro individual

Use certificados X.509 com um registro individual para testar o seu dispositivo e a sua solução. Em um registro individual, não há nenhum certificado X.509 raiz ou intermediário no aplicativo do 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 de registro individual, que são usados para registrar um dispositivo. Os certificados autoassinados são somente para teste.

Aviso

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

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 

Dica

Uma identificação do dispositivo pode conter letras, números e o caractere -.

Esses comandos produzem os seguintes certificados do dispositivo:

filename conteúdos
mytestselfcertprimary_cert.pem A parte pública do certificado X509 do dispositivo
mytestselfcertprimary_key.pem A chave privada do certificado X509 do dispositivo primário
mytestselfcertprimary_fullchain.pem O conjunto de chaves inteiro do certificado X509 do dispositivo primário.
mytestselfcertprimary.pfx O arquivo PFX do 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 do certificado X509 do dispositivo secundário
mytestselfcertsecondary_fullchain.pem O conjunto de chaves inteiro do certificado X509 do dispositivo secundário.
mytestselfcertsecondary.pfx O arquivo PFX do certificado X509 do dispositivo secundário.

Criar registro individual

  1. No aplicativo do Azure IoT Central, selecione Dispositivos e crie um dispositivo com a ID do dispositivo como mytestselfcertprimary por meio do modelo de dispositivo de termostato. Anote o valor do escopo da ID, você o usará mais tarde.

  2. Abra o dispositivo que você criou e selecione Conectar.

  3. Selecione registro 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 Salvar.

  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 dispositivo de registro individual de exemplo

Se estiver usando Windows, os certificados X.509 deverão estar no repositório 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, insira 1234 como a senha e deixe o assistente escolher o repositório de certificados automaticamente. O assistente importa os certificados para o repositório pessoal do usuário atual.

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

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

  2. Adicione as duas definições seguintes de parâmetro para a 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");
    

    Salve as alterações.

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

  4. Adicione as seguintes declarações de 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 SetupDeviceClientAsync, substitua o bloco de códigos por 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 seguinte código:

    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);
    }
    

    Salve 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 o aplicativo. Verifique se o dispositivo foi provisionado com êxito.

Para modificar o código de exemplo a fim de 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 até a pasta src com o arquivo de exemplo do controlador de temperatura.

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

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

    Salve as alterações.

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

  4. Substitua a importação SecurityProviderSymmetricKey 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 importação a seguir:

    import java.nio.file.*;
    
  6. Adicione SecurityProviderException à lista de exceções geradas pelo método main:

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

    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();
        }
    }
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Compile e execute o aplicativo. Verifique se o dispositivo foi provisionado com êxito.

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

Para modificar o código de exemplo a fim de 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 instruções require para incluir o seguinte:

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

    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 função provisionDevice que cria o cliente substituindo a primeira linha pelo código seguinte:

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

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

    client.setOptions(deviceCert);
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Execute o script e verifique se o dispositivo foi provisionado com êxito:

    node pnp_temperature_controller.js
    

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

Para modificar o código de exemplo a fim de 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 instrução from para importar a funcionalidade X.509:

    from azure.iot.device import X509
    
  3. Modifique a primeira parte da função provision_device 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. Na função main, substitua a linha que define a variável symmetric_key com o seguinte código:

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

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. Na função main, substitua a chamada para a função IoTHubDeviceClient.create_from_symmetric_key pelo 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,
    )
    

    Salve as alterações.

Para executar o exemplo:

  1. No ambiente do shell, defina as duas variáveis de ambiente abaixo. Certifique-se de fornecer o caminho completo para os arquivos PEM e use 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
    

    Dica

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

  2. Execute o script e verifique se o dispositivo foi provisionado com êxito:

    python temp_controller_with_thermostats.py
    

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

Conectar um dispositivo do IoT Edge

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

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

  • Copie os certificado de dispositivo e os arquivos de chave em seu dispositivo do IoT Edge. No exemplo de registro de grupo anterior, esses arquivos foram nomeados sampleDevice01_key.pem e sampleDevice01_cert.pem.

  • No dispositivo do IoT Edge, edite a seção provisioning 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"
    

    Dica

    Não é necessário adicionar um valor de registration_id. O IoT Edge pode usar o valor de CN do certificado X.509.

  • Execute o seguinte comando para reiniciar o runtime do IoT Edge:

    sudo iotedge config apply
    

Para obter mais informações, confira Criar e provisionar dispositivos do 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 do IoT Edge que funciona como um gateway transparente. Para saber mais sobre como configurar este cenário, confira Conectar um dispositivo downstream a um gateway do Azure IoT Edge.

Role seus certificados de dispositivo X.509

Durante o ciclo de vida da sua aplicação IoT Central, poderá ser necessário lançar os seus certificados X.509. Por exemplo:

  • No caso de uma violação de segurança, a implantação de certificados é uma melhor prática de segurança para ajudar a proteger seu sistema.
  • Os certificados X.509 têm datas de expiração. A frequência de distribuição dos seus certificados dependerá das necessidades de segurança da sua solução. Os clientes com soluções que envolvem dados altamente confidenciais podem lançar certificados diariamente, enquanto outros lançam seus certificados a cada dois anos.

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

Para saber mais, veja Metodologia de pressuposição de violação.

Esta seção descreve como distribuir os certificados no IoT Central. Ao distribuir 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. Crie seus certificados X.509 usando uma ferramenta como o OpenSSL. Essa abordagem é útil para testar os certificados x.509, mas fornece poucas garantias em relação à segurança. Só use essa abordagem para testes, a menos que você esteja preparado para atuar como seu próprio provedor de autoridade de certificação.

Grupos de registro 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 abordagem seguinte, que atualiza o certificado atual imediatamente. Conclua essas etapas para os certificados primário e secundário, se ambos estiverem comprometidos:

  1. Navegue até Permissões no painel à esquerda e selecione Grupos de conexões de dispositivo.

  2. Selecione o nome do grupo na lista em Grupos de registro.

  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 registro.

Registros individuais e violações de segurança

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

  1. Selecione Dispositivos e depois o dispositivo.

  2. Selecione Conectar e depois Conectar método como Registro Individual

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

  4. Para atualização do certificado, selecione o ícone da pasta a fim de escolher o novo certificado a ser carregado para a entrada de registro. Selecione Salvar.

Grupos de registro e expiração do certificado

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

  1. Navegue até Permissões no painel à esquerda e selecione Grupos de conexões de dispositivo.

  2. Selecione o nome do grupo na lista em Grupos de registro.

  3. Para atualização de certificado, selecione Gerenciar Primário.

  4. Adicione e verifique o certificado raiz X.509 no grupo de registro.

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

Registros individuais e a expiração do certificado

Se você estiver implantando certificados para processar as expirações de certificado, deve usar a configuração de certificado secundário da seguinte maneira para reduzir o tempo de inatividade para dispositivos que tentam provisionar no seu aplicativo.

Quando o certificado secundário se aproximar da expiração e precisar ser implantado, você poderá rotacionar usando a configuração primária. Fazer uma rotação entre os certificados primários e secundários dessa maneira reduz o tempo de inatividade para dispositivos que tentam provisionar no seu aplicativo.

  1. Selecione Dispositivos e depois o dispositivo.

  2. Selecione Conectar e depois Conectar método como Registro Individual

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

  4. Para atualização do certificado secundário, selecione o ícone da pasta a fim de escolher o novo certificado a ser carregado para a entrada de registro. Selecione Salvar.

  5. Posteriormente, quando o certificado primário tiver expirado, volte e atualize-o.