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.
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
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
Abra o aplicativo do IoT Central e navegue até Permissões no painel esquerdo e selecione Grupos de conexão de dispositivo.
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.
No grupo de registro que você criou, selecione Gerenciar primário.
No painel de Certificado primário, selecione Adicionar certificado.
Carregue o arquivo do certificado raiz chamado mytestrootcert_cert.pem que você gerou anteriormente.
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.
Se você definir o status do certificado verificado no upload para Desativado, selecione Gerar código de verificação.
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}
Selecione Verificar para carregar o certificado de verificação assinado verification_cert.pem para concluir a verificação:
O status do certificado primário agora é Verificado:
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:
Na solução IoTHubDeviceSamples do Visual Studio, abra o arquivo Parameter.cs no projeto TemperatureController.
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.
Na solução IoTHubDeviceSamples do Visual Studio, abra o arquivo Program.cs no projeto TemperatureController.
Adicione as seguintes declarações de
using
:using System.Security.Cryptography.X509Certificates; using System.IO;
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; }
No método
SetupDeviceClientAsync
, substitua o bloco de códigos porcase "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;
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:
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.
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:
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.
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.
Abra o arquivo src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java em seu editor de texto.
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;
Adicione a importação a seguir:
import java.nio.file.*;
Adicione
SecurityProviderException
à lista de exceções geradas pelo métodomain
:public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
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:
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.
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:
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
Abra o arquivo pnp_temperature_controller.js em um editor de texto.
Edite as instruções
require
para incluir o seguinte:const fs = require('fs'); const X509Security = require('azure-iot-security-x509').X509Security;
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() };
Edite a função
provisionDevice
que cria o cliente substituindo a primeira linha pelo código seguinte:var provSecurityClient = new X509Security(registrationId, deviceCert);
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';
Na função
main
, adicione a seguinte linha após a linha que chamaClient.fromConnectionString
:client.setOptions(deviceCert);
Salve as alterações.
Para executar o exemplo:
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.
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:
Navegue até a pasta azure-iot-device/samples/pnp e abra o arquivo temp_controller_with_thermostats.py em um editor de texto.
Adicione a seguinte instrução
from
para importar a funcionalidade X.509:from azure.iot.device import X509
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, )
Na função
main
, substitua a linha que define a variávelsymmetric_key
com o seguinte código:x509 = X509( cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"), key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"), )
Na função
main
, substitua a chamada para a funçãoprovision_device
pelo seguinte código:registration_result = await provision_device( provisioning_host, id_scope, registration_id, x509, model_id )
Na função
main
, substitua a chamada para a funçãoIoTHubDeviceClient.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:
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.
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:
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
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.
Abra o dispositivo que você criou e selecione Conectar.
Selecione registro individual como o Tipo de autenticação e Certificados (X.509) como o Método de autenticação.
Carregue o arquivo mytestselfcertprimary_cert.pem que você gerou anteriormente como o certificado primário.
Carregue o arquivo mytestselfcertsecondary_cert.pem que você gerou anteriormente como o certificado secundário. Em seguida, selecione Salvar.
O dispositivo agora tem um registro individual com certificados X.509.
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:
Na solução IoTHubDeviceSamples do Visual Studio, abra o arquivo Parameter.cs no projeto TemperatureController.
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.
Na solução IoTHubDeviceSamples do Visual Studio, abra o arquivo Program.cs no projeto TemperatureController.
Adicione as seguintes declarações de
using
:using System.Security.Cryptography.X509Certificates; using System.IO;
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; }
No método
SetupDeviceClientAsync
, substitua o bloco de códigos porcase "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;
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:
Adicione as seguintes variáveis de ambiente ao projeto:
IOTHUB_DEVICE_DPS_DEVICE_ID
: mytestselfcertprimaryIOTHUB_DEVICE_X509_CERT
:<full path to folder that contains PFX files>mytestselfcertprimary.pfx
IOTHUB_DEVICE_X509_PASSWORD
: 1234.
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:
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.
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.
Abra o arquivo src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java em seu editor de texto.
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;
Adicione a importação a seguir:
import java.nio.file.*;
Adicione
SecurityProviderException
à lista de exceções geradas pelo métodomain
:public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
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:
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.
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:
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
Abra o arquivo pnp_temperature_controller.js em um editor de texto.
Edite as instruções
require
para incluir o seguinte:const fs = require('fs'); const X509Security = require('azure-iot-security-x509').X509Security;
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() };
Edite a função
provisionDevice
que cria o cliente substituindo a primeira linha pelo código seguinte:var provSecurityClient = new X509Security(registrationId, deviceCert);
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';
Na função
main
, adicione a seguinte linha após a linha que chamaClient.fromConnectionString
:client.setOptions(deviceCert);
Salve as alterações.
Para executar o exemplo:
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.
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:
Navegue até a pasta azure-iot-device/samples/pnp e abra o arquivo temp_controller_with_thermostats.py em um editor de texto.
Adicione a seguinte instrução
from
para importar a funcionalidade X.509:from azure.iot.device import X509
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, )
Na função
main
, substitua a linha que define a variávelsymmetric_key
com o seguinte código:x509 = X509( cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"), key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"), )
Na função
main
, substitua a chamada para a funçãoprovision_device
pelo seguinte código:registration_result = await provision_device( provisioning_host, id_scope, registration_id, x509, model_id )
Na função
main
, substitua a chamada para a funçãoIoTHubDeviceClient.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:
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.
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:
Navegue até Permissões no painel à esquerda e selecione Grupos de conexões de dispositivo.
Selecione o nome do grupo na lista em Grupos de registro.
Para atualização de certificado, selecione Gerenciar primário ou Gerenciar secundário.
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:
Selecione Dispositivos e depois o dispositivo.
Selecione Conectar e depois Conectar método como Registro Individual
Selecione Certificados (X.509) como mecanismo.
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:
Navegue até Permissões no painel à esquerda e selecione Grupos de conexões de dispositivo.
Selecione o nome do grupo na lista em Grupos de registro.
Para atualização de certificado, selecione Gerenciar Primário.
Adicione e verifique o certificado raiz X.509 no grupo de registro.
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.
Selecione Dispositivos e depois o dispositivo.
Selecione Conectar e depois Conectar método como Registro Individual
Selecione Certificados (X.509) como mecanismo.
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.
Posteriormente, quando o certificado primário tiver expirado, volte e atualize-o.