Share via


Come connettere i dispositivi con certificati X.509 all'applicazione IoT Central

IoT Central supporta sia le firme di accesso condiviso (SAS) che i certificati X.509 per proteggere la comunicazione tra un dispositivo e l'applicazione. L'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central usa la firma di accesso condiviso. Questo articolo illustra come modificare l'esempio di codice per usare i certificati X.509. Negli ambienti di produzione è consigliabile usare i certificati X.509. Per altre informazioni, vedere Concetti relativi all'autenticazione del dispositivo.

Questa guida illustra due modi per usare i certificati X.509: le registrazioni di gruppo in genere usate in un ambiente di produzione e le registrazioni singole utili per i test. L'articolo descrive anche come implementare i certificati del dispositivo per mantenere la connettività alla scadenza dei certificati.

Questa guida si basa sugli esempi illustrati nell'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central che usa C#, Java, JavaScript e Python. Per un esempio che usa il linguaggio di programmazione C, vedere Effettuare il provisioning di più dispositivi X.509 usando i gruppi di registrazione.

Prerequisiti

Per completare i passaggi descritti in questa guida pratica, è necessario prima completare l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central .

In questa guida pratica vengono generati alcuni certificati X.509 di test. Per poter generare questi certificati, è necessario:

  • Un computer di sviluppo con Node.js versione 6 o successiva installato. Per controllare la versione, è possibile eseguire node --version nella riga di comando. Le istruzioni riportate in questa esercitazione presuppongono che il comando node venga eseguito al prompt dei comandi di Windows. È tuttavia possibile usare Node.js in numerosi altri sistemi operativi.
  • Copia locale di Microsoft Azure IoT SDK per Node.js repository GitHub che contiene gli script per generare i certificati X.509 di test. Usare questo collegamento per scaricare una copia del repository: Scarica lo ZIP. Quindi decomprimere il file in un percorso appropriato nel computer locale.

Usare la registrazione del gruppo

Usare certificati X.509 con una registrazione di gruppo in un ambiente di produzione. In una registrazione di gruppo si aggiunge un certificato X.509 radice o intermedio all'applicazione IoT Central. I dispositivi con certificati foglia derivati dal certificato radice o intermedio possono connettersi all'applicazione.

Generare certificati radice e dispositivo

In questa sezione si usa un certificato X.509 per connettere un dispositivo con un certificato derivato dal certificato del gruppo di registrazione di IoT Central.

Avviso

Questo modo di generare certificati X.509 è solo per i test. Per un ambiente di produzione è consigliabile usare il meccanismo ufficiale e sicuro per la generazione di certificati.

  1. Passare allo script del generatore di certificati in Microsoft Azure IoT SDK per Node.js scaricato. Installare i pacchetti necessari:

    cd azure-iot-sdk-node/provisioning/tools
    npm install
    
  2. Creare un certificato radice e quindi derivare un certificato del dispositivo eseguendo lo script:

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

    Suggerimento

    Un ID dispositivo può contenere lettere, numeri e il carattere -.

Questi comandi producono la radice e il certificato del dispositivo seguenti

nomefile sommario
mytestrootcert_cert.pem Parte pubblica del certificato X509 radice
mytestrootcert_key.pem Chiave privata per il certificato X509 radice
mytestrootcert_fullchain.pem L'intero portachiavi per il certificato X509 radice.
mytestrootcert.pfx File PFX per il certificato X509 radice.
sampleDevice01_cert.pem Parte pubblica del certificato X509 del dispositivo
sampleDevice01_key.pem Chiave privata per il certificato X509 del dispositivo
sampleDevice01_fullchain.pem L'intero portachiavi per il certificato X509 del dispositivo.
sampleDevice01.pfx File PFX per il certificato X509 del dispositivo.

Prendere nota del percorso di questi file. Sarà necessario in un secondo momento.

Creare una registrazione di gruppo

  1. Aprire l'applicazione IoT Central e passare a Autorizzazioni nel riquadro sinistro e selezionare Gruppi di connessioni del dispositivo.

  2. Selezionare + Nuovo per creare un nuovo gruppo di registrazioni denominato MyX509Group con un tipo di attestazione Certificati (X.509). È possibile creare gruppi di registrazione per dispositivi IoT o IoT Edge dispositivi.

  3. Nel gruppo di registrazione creato selezionare Gestisci primario.

  4. Nel pannello Certificato primario selezionare Aggiungi certificato.

  5. Caricare il file del certificato radice denominato mytestrootcert_cert.pem generato in precedenza.

  6. Se si usa un'autorità di certificazione intermedia o radice attendibile e si conosce la proprietà completa del certificato, è possibile attestare automaticamente che il certificato è stato verificato impostando lo stato del certificato verificato durante il caricamento su . In caso contrario, impostare lo stato del certificato verificato al caricamento su Disattivato.

  7. Se si imposta lo stato del certificato verificato durante il caricamento su Disattivato, selezionare Genera codice di verifica.

  8. Copiare il codice di verifica, copiarlo e quindi creare un certificato di verifica X.509. Ad esempio, al prompt dei comandi:

    node create_test_cert.js verification --ca mytestrootcert_cert.pem --key mytestrootcert_key.pem --nonce  {verification-code}
    
  9. Selezionare Verifica per caricare il certificato di verifica firmato verification_cert.pem per completare la verifica.

  10. Lo stato del certificato primario è ora Verificato:

    Screenshot che mostra un certificato X509 verificato.

È ora possibile connettere i dispositivi con un certificato X.509 derivato da questo certificato radice primario.

Dopo aver salvato il gruppo di registrazione, prendere nota dell'ambito ID.

Eseguire il codice del dispositivo di esempio

Se si usa Windows, i certificati X.509 devono trovarsi nell'archivio certificati di Windows per consentire il funzionamento dell'esempio. In Esplora risorse fare doppio clic sui file PFX generati in precedenza e mytestrootcert.pfxsampleDevice01.pfx. Nell'Importazione guidata certificati selezionare Utente corrente come percorso dell'archivio, immettere 1234 come password e consentire alla procedura guidata di scegliere automaticamente l'archivio certificati. La procedura guidata importa i certificati nell'archivio personale dell'utente corrente.

Per modificare il codice di esempio per usare i certificati X.509:

  1. Nella soluzione IoTHubDeviceSamples di Visual Studio aprire il file Parameter.cs nel progetto TemperatureController .

  2. Aggiungere le due definizioni di parametro seguenti alla 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");
    

    Salvare le modifiche.

  3. Nella soluzione IoTHubDeviceSamples di Visual Studio aprire il file Program.cs nel progetto TemperatureController .

  4. Aggiungere le istruzioni using seguenti:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Aggiungere il metodo seguente alla 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. SetupDeviceClientAsync Nel metodo sostituire il blocco di codice per case "dps" con il codice seguente:

    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. Sostituire il metodo ProvisionDeviceAsync con il codice seguente:

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

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Aggiungere le variabili di ambiente seguenti al progetto:

    • IOTHUB_DEVICE_X509_CERT: <full path to folder that contains PFX files>sampleDevice01.pfx
    • IOTHUB_DEVICE_X509_PASSWORD: 1234.
  2. Compilare ed eseguire l'applicazione. Verificare che il dispositivo sia stato effettuato correttamente.

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample che contiene il file pom.xml e la cartella src per l'esempio di dispositivo del controller di temperatura.

  2. Modificare il file pom.xml per aggiungere la configurazione di dipendenza seguente nel <dependencies> nodo:

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

    Salvare le modifiche.

  3. Aprire il file src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java nell'editor di testo.

  4. Sostituire l'importazione SecurityProviderSymmetricKey con le importazioni seguenti:

    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. Aggiungere l'importazione seguente:

    import java.nio.file.*;
    
  6. Aggiungere SecurityProviderException all'elenco di eccezioni generate dal main metodo:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Sostituire il metodo initializeAndProvisionDevice con il codice seguente:

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

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Compilare ed eseguire l'applicazione. Verificare che il dispositivo venga eseguito correttamente.

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-sdk-node/device/samples/javascript che contiene l'applicazione pnp_temperature_controller.js ed eseguire il comando seguente per installare il pacchetto X.509:

    npm install azure-iot-security-x509 --save
    
  2. Aprire il file dipnp_temperature_controller.js in un editor di testo.

  3. Modificare le require istruzioni per includere il codice seguente:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Aggiungere le quattro righe seguenti alla sezione "Informazioni di connessione DPS" per inizializzare la deviceCert variabile:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Modificare la funzione che crea il provisionDevice client sostituendo la prima riga con il codice seguente:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. Nella stessa funzione modificare la riga che imposta la deviceConnectionString variabile come indicato di seguito:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main Nella funzione aggiungere la riga seguente dopo la riga che chiama Client.fromConnectionString:

    client.setOptions(deviceCert);
    

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Eseguire lo script e verificare il provisioning del dispositivo correttamente:

    node pnp_temperature_controller.js
    

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-device/samples/pnp e aprire il file temp_controller_with_thermostats.py in un editor di testo.

  2. Aggiungere l'istruzione seguente from per importare la funzionalità X.509:

    from azure.iot.device import X509
    
  3. Modificare la prima parte della provision_device funzione come indicato di seguito:

    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 Nella funzione sostituire la riga che imposta la variabile con il symmetric_key codice seguente:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. main Nella funzione sostituire la chiamata alla provision_device funzione con il codice seguente:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. main Nella funzione sostituire la chiamata alla IoTHubDeviceClient.create_from_symmetric_key funzione con il codice seguente:

    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,
    )
    

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Eseguire lo script e verificare il provisioning del dispositivo correttamente:

    python temp_controller_with_thermostats.py
    

Verificare che i dati di telemetria vengano visualizzati nella visualizzazione del dispositivo nell'applicazione IoT Central:

Screenshot che mostra i dati di telemetria da un dispositivo connesso con X.509.

Usare la registrazione singola

Usare i certificati X.509 con una registrazione singola per testare il dispositivo e la soluzione. In una singola registrazione non è presente alcun certificato X.509 radice o intermedio nell'applicazione IoT Central. I dispositivi usano un certificato X.509 autofirmato per connettersi all'applicazione.

Generare un certificato del dispositivo autofirmato

In questa sezione viene usato un certificato X.509 autofirmato per connettere i dispositivi per la registrazione singola, che vengono usati per registrare un singolo dispositivo. I certificati autofirmati sono solo per i test.

Avviso

Questo modo di generare certificati X.509 è solo per i test. Per un ambiente di produzione è consigliabile usare il meccanismo ufficiale e sicuro per la generazione di certificati.

Creare un certificato dispositivo X.509 autofirmato eseguendo i comandi seguenti:

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

Suggerimento

Un ID dispositivo può contenere lettere, numeri e il carattere -.

Questi comandi producono i certificati del dispositivo seguenti:

nomefile sommario
mytestselfcertprimary_cert.pem Parte pubblica del certificato X509 del dispositivo primario
mytestselfcertprimary_key.pem Chiave privata per il certificato X509 del dispositivo primario
mytestselfcertprimary_fullchain.pem L'intera keychain per il certificato X509 del dispositivo primario.
mytestselfcertprimary.pfx File PFX per il certificato X509 del dispositivo primario.
mytestselfcertsecondary_cert.pem Parte pubblica del certificato X509 del dispositivo secondario
mytestselfcertsecondary_key.pem Chiave privata per il certificato X509 del dispositivo secondario
mytestselfcertsecondary_fullchain.pem L'intera keychain per il certificato X509 del dispositivo secondario.
mytestselfcertsecondary.pfx File PFX per il certificato X509 del dispositivo secondario.

Creare una registrazione singola

  1. Nell'applicazione Azure IoT Central selezionare Dispositivi e creare un nuovo dispositivo con ID dispositivo come mytestcertprimary dal modello di dispositivo termostato. Prendere nota dell'ambito ID, usarlo in un secondo momento.

  2. Aprire il dispositivo creato e selezionare Connetti.

  3. Selezionare Registrazione singola come tipo di autenticazione e certificati (X.509) come metodo Authentication.

  4. Caricare il file mytestselfcertprimary_cert.pem generato in precedenza come certificato primario.

  5. Caricare il file mytestselfcertsecondary_cert.pem generato in precedenza come certificato secondario. Selezionare quindi Salva.

  6. Il dispositivo ha ora una registrazione singola con certificati X.509.

    Screenshot che mostra come connettere un dispositivo usando una registrazione singola X.509.

Eseguire un singolo dispositivo di registrazione di esempio

Se si usa Windows, i certificati X.509 devono trovarsi nell'archivio certificati di Windows per il funzionamento dell'esempio. In Esplora risorse fare doppio clic sui file PFX generati in precedenza e mytestselfcertprimary.pfxmytestselfcertsecondary.pfx. Nella Procedura guidata Importazione certificati selezionare Utente corrente come percorso dell'archivio, immettere 1234 come password e consentire alla procedura guidata di scegliere automaticamente l'archivio certificati. La procedura guidata importa i certificati nell'archivio personale dell'utente corrente.

Per modificare il codice di esempio per usare i certificati X.509:

  1. Nella soluzione IoTHubDeviceSamples Visual Studio aprire il file Parameter.cs nel progetto TemperatureController .

  2. Aggiungere le due definizioni di parametri seguenti alla 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");
    

    Salvare le modifiche.

  3. Nella soluzione IoTHubDeviceSamples Visual Studio aprire il file Program.cs nel progetto TemperatureController .

  4. Aggiungere le istruzioni using seguenti:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Aggiungere il metodo seguente alla 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. SetupDeviceClientAsync Nel metodo sostituire il blocco di codice per case "dps" con il codice seguente:

    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. Sostituire il metodo ProvisionDeviceAsync con il codice seguente:

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

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Aggiungere le variabili di ambiente seguenti al progetto:

    • 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. Compilare ed eseguire l'applicazione. Verificare che il dispositivo venga eseguito correttamente.

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample che contiene il file pom.xml e la cartella src per l'esempio di dispositivo del controller di temperatura.

  2. Modificare il file pom.xml per aggiungere la configurazione di dipendenza seguente nel <dependencies> nodo:

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

    Salvare le modifiche.

  3. Aprire il file src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java nell'editor di testo.

  4. Sostituire l'importazione SecurityProviderSymmetricKey con le importazioni seguenti:

    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. Aggiungere l'importazione seguente:

    import java.nio.file.*;
    
  6. Aggiungere SecurityProviderException all'elenco di eccezioni generate dal main metodo:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Sostituire il metodo initializeAndProvisionDevice con il codice seguente:

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

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Compilare ed eseguire l'applicazione. Verificare che il dispositivo venga eseguito correttamente.

È anche possibile ripetere i passaggi precedenti per il certificato mytestcertsecondary .

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-sdk-node/device/samples/javascript che contiene l'applicazione pnp_temperature_controller.js ed eseguire il comando seguente per installare il pacchetto X.509:

    npm install azure-iot-security-x509 --save
    
  2. Aprire il file dipnp_temperature_controller.js in un editor di testo.

  3. Modificare le require istruzioni per includere il codice seguente:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Aggiungere le quattro righe seguenti alla sezione "Informazioni di connessione DPS" per inizializzare la deviceCert variabile:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Modificare la funzione che crea il provisionDevice client sostituendo la prima riga con il codice seguente:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. Nella stessa funzione modificare la riga che imposta la deviceConnectionString variabile come indicato di seguito:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main Nella funzione aggiungere la riga seguente dopo la riga che chiama Client.fromConnectionString:

    client.setOptions(deviceCert);
    

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Eseguire lo script e verificare il provisioning del dispositivo correttamente:

    node pnp_temperature_controller.js
    

È anche possibile ripetere i passaggi precedenti per il certificato mytestcertsecondary .

Per modificare il codice di esempio per usare i certificati X.509:

  1. Passare alla cartella azure-iot-device/samples/pnp e aprire il file temp_controller_with_thermostats.py in un editor di testo.

  2. Aggiungere l'istruzione seguente from per importare la funzionalità X.509:

    from azure.iot.device import X509
    
  3. Modificare la prima parte della provision_device funzione come indicato di seguito:

    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 Nella funzione sostituire la riga che imposta la variabile con il symmetric_key codice seguente:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. main Nella funzione sostituire la chiamata alla provision_device funzione con il codice seguente:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. main Nella funzione sostituire la chiamata alla IoTHubDeviceClient.create_from_symmetric_key funzione con il codice seguente:

    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,
    )
    

    Salvare le modifiche.

Per eseguire l'esempio:

  1. Nell'ambiente shell aggiungere le due variabili di ambiente seguenti. Assicurarsi di fornire il percorso completo ai file PEM e usare il delimitatore di percorso corretto per il sistema operativo:

    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
    

    Suggerimento

    Dopo aver completato l'esercitazione Creare e connettere un'applicazione client all'applicazione Azure IoT Central , impostare le altre variabili di ambiente necessarie.

  2. Eseguire lo script e verificare il provisioning del dispositivo correttamente:

    python temp_controller_with_thermostats.py
    

È anche possibile ripetere i passaggi precedenti per il certificato mytestcertsecondary .

Connettere un dispositivo IoT Edge

In questa sezione si presuppone che si usi una registrazione di gruppo per connettere il dispositivo IoT Edge. Seguire la procedura descritta nelle sezioni precedenti per:

Per connettere il dispositivo IoT Edge a IoT Central usando il certificato del dispositivo X.509:

  • Copiare il certificato del dispositivo e i file di chiave nel dispositivo IoT Edge. Nell'esempio di registrazione del gruppo precedente, questi file sono stati chiamati sampleDevice01_key.pem e sampleDevice01_cert.pem.

  • Nel dispositivo IoT Edge, modificare provisioning la sezione nel file di configurazione /etc/aziot/config.toml come indicato di seguito:

    # 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"
    

    Suggerimento

    Non è necessario aggiungere un valore per .registration_id IoT Edge può usare il valore CN dal certificato X.509.

  • Eseguire il comando seguente per riavviare il runtime di IoT Edge:

    sudo iotedge config apply
    

Per altre informazioni, vedere Creare e effettuare il provisioning di dispositivi IoT Edge su larga scala su Linux usando certificati X.509.

Connettere un dispositivo downstream a IoT Edge

IoT Edge usa certificati X.509 per proteggere la connessione tra dispositivi downstream e un dispositivo IoT Edge funge da gateway trasparente. Per altre informazioni sulla configurazione di questo scenario, vedere Connettere un dispositivo downstream a un gateway di IoT Edge di Azure.

Roll X.509 device certificates (Roll X.509 device certificate)

Durante il ciclo di vita dell'applicazione IoT Central, è necessario implementare i certificati x.509. Ad esempio:

  • Se si ha una violazione della sicurezza, i certificati in sequenza sono una procedura consigliata per la sicurezza per proteggere il sistema.
  • I certificati x.509 hanno date di scadenza. La frequenza in cui si esegue il rollback dei certificati dipende dalle esigenze di sicurezza della soluzione. I clienti con soluzioni che coinvolgono dati altamente sensibili possono implementare i certificati ogni giorno, mentre altri rollbackno i certificati ogni paio di anni.

Per la connettività senza interruzioni, IoT Central consente di configurare certificati X.509 primari e secondari. Se i certificati primari e secondari hanno date di scadenza diverse, è possibile eseguire il rollback del certificato scaduto mentre i dispositivi continuano a connettersi con l'altro certificato.

Per altre informazioni, vedere Presupporre la metodologia di violazione.

Questa sezione descrive come eseguire il rollback dei certificati in IoT Central. Quando si esegue il rollback di un certificato in IoT Central, è anche necessario copiare il nuovo certificato del dispositivo nei dispositivi.

Ottenere nuovi certificati X.509

Ottenere nuovi certificati X.509 dal provider di certificati. È possibile creare certificati X.509 personalizzati usando uno strumento come OpenSSL. Questo approccio è utile per il test dei certificati X.509, ma offre alcune garanzie di sicurezza. Usare questo approccio solo per il test, a meno che non si sia preparati ad agire come provider di CA.

Gruppi di registrazioni e violazioni della sicurezza

Per aggiornare una registrazione del gruppo in risposta a una violazione della sicurezza, è consigliabile usare l'approccio seguente per aggiornare immediatamente il certificato corrente. Completare questi passaggi per i certificati primari e secondari se entrambi sono compromessi:

  1. Passare a Autorizzazioni nel riquadro sinistro e selezionare Gruppi di connessioni dispositivo.

  2. Selezionare il nome del gruppo nell'elenco in Gruppi di registrazione.

  3. Per l'aggiornamento del certificato selezionare Gestisci primario o Gestisci secondario.

  4. Aggiungere e verificare il certificato X.509 radice nel gruppo di registrazione.

Registrazioni singole e violazioni della sicurezza

Se si esegue il rollback dei certificati in risposta a una violazione della sicurezza, usare l'approccio seguente per aggiornare immediatamente il certificato corrente. Completare questi passaggi per i certificati primari e secondari, se entrambi sono compromessi:

  1. Selezionare Dispositivi e selezionare il dispositivo.

  2. Selezionare Connetti e selezionare Connect method (Connetti) come Registrazione singola

  3. Selezionare Certificati (X.509) come meccanismo.

  4. Per l'aggiornamento del certificato, selezionare l'icona della cartella per selezionare il nuovo certificato da caricare per la voce di registrazione. Selezionare Salva.

Gruppi di registrazione e scadenza del certificato

Per gestire le scadenze dei certificati, usare l'approccio seguente per aggiornare immediatamente il certificato corrente:

  1. Passare a Autorizzazioni nel riquadro sinistro e selezionare Gruppi di connessione del dispositivo.

  2. Selezionare il nome del gruppo nell'elenco in Gruppi di registrazione.

  3. Per l'aggiornamento del certificato selezionare Gestisci primario.

  4. Aggiungere e verificare il certificato X.509 radice nel gruppo di registrazioni.

  5. Successivamente, quando il certificato secondario è scaduto, tornare e aggiornare il certificato secondario.

Registrazioni singole e scadenza del certificato

Se si stanno eseguendo i certificati in sequenza per gestire le scadenze dei certificati, è consigliabile usare la configurazione del certificato secondario come indicato di seguito per ridurre i tempi di inattività per i dispositivi che tentano di effettuare il provisioning nell'applicazione.

Quando il certificato secondario si avvicina alla scadenza e deve essere eseguito il rollback, è possibile eseguire la rotazione in usando la configurazione primaria. La rotazione tra i certificati primari e secondari in questo modo riduce i tempi di inattività per i dispositivi che tentano di effettuare il provisioning nell'applicazione.

  1. Selezionare Dispositivi e selezionare il dispositivo.

  2. Selezionare Connetti e selezionare Connect method (Connetti) come Registrazione singola

  3. Selezionare Certificati (X.509) come meccanismo.

  4. Per l'aggiornamento del certificato secondario, selezionare l'icona della cartella per selezionare il nuovo certificato da caricare per la voce di registrazione. Selezionare Salva.

  5. Successivamente, quando il certificato primario è scaduto, tornare e aggiornare il certificato primario.

Passaggi successivi

Dopo aver appreso come connettere i dispositivi usando certificati X.509, il passaggio successivo consigliato consiste nel monitorare la connettività dei dispositivi usando l'interfaccia della riga di comando di Azure.