Поделиться через


Подключение устройств с сертификатами X.509 к приложению IoT Central

IoT Central поддерживает подписанные URL-адреса (SAS) и сертификаты X.509 для защиты связи между устройством и приложением. В руководстве по созданию и подключению клиентского приложения к приложению Azure IoT Central используется SAS. Из этой статьи вы узнаете, как изменить пример кода для использования сертификатов X.509. Сертификаты X.509 рекомендуется использовать в рабочих средах. Дополнительные сведения см. в разделе "Основные понятия проверки подлинности устройств" в IoT Central.

В этом руководстве показаны два способа использования сертификатов X.509 — групповые регистрации , которые обычно используются в рабочей среде, и отдельные регистрации , полезные для тестирования. В статье также описывается, как обновить сертификаты устройств для поддержания подключения при истечении срока действия сертификатов.

В этом руководстве приведены примеры, приведенные в руководстве по созданию и подключению клиентского приложения к приложению Azure IoT Central , использующим C#, Java, JavaScript и Python. Пример использования языка программирования C см. в руководстве по подготовке нескольких устройств X.509 с помощью групп регистрации .

Предпосылки

Чтобы выполнить действия, описанные в этом руководстве, сначала пройдите учебный курс Создание и подключение клиентского приложения к приложению Azure IoT Central. При выполнении действий, описанных в этом руководстве, вы изменяете код, используемый в этом руководстве.

В этом руководстве вы создаете некоторые тестовые сертификаты X.509. Чтобы создать эти сертификаты, вам потребуется:

  • Машина для разработки с установленным Node.js версии 6 или более поздней. Чтобы проверить версию, можно запустить node --version в командной строке. Инструкции в этом учебнике предполагают, что вы запускаете команду node в командной строке Windows. Однако вы можете использовать Node.js во многих других операционных системах.
  • Локальная копия Microsoft Azure IoT SDK для Node.js из репозитория GitHub, содержащая скрипты для генерации тестовых сертификатов X.509. Используйте эту ссылку, чтобы скачать копию репозитория: скачать ZIP-файл. Затем распакуйте файл в подходящее расположение на локальном компьютере.

Использование регистрации групп

Используйте сертификаты X.509 с групповой регистрацией в рабочей среде. В группе регистрации вы добавляете корневой или промежуточный сертификат X.509 в приложение IoT Central. Устройства с листовыми сертификатами, производными от корневого или промежуточного сертификата, могут подключаться к вашему приложению.

Создание корневых сертификатов и сертификатов устройств

В этом разделе вы используете сертификат X.509 для подключения устройства с сертификатом, созданным на основе сертификата группы регистрации IoT Central.

Предупреждение

Этот способ создания сертификатов X.509 предназначен только для тестирования. Для рабочей среды следует использовать официальный безопасный механизм для создания сертификатов.

  1. Перейдите к скрипту генератора сертификатов в загруженном вами пакете Microsoft Azure IoT SDK для Node.js. Установите необходимые пакеты:

    cd azure-iot-sdk-node/provisioning/tools
    npm install
    
  2. Создайте корневой сертификат и затем создайте сертификат устройства, запустив скрипт.

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

    Подсказка

    Идентификатор устройства может содержать буквы, цифры и - символ.

Эти команды создают следующие корневые сертификаты и сертификаты устройства:

filename contents
mytestrootcert_cert.pem Общедоступная часть корневого сертификата X509
mytestrootcert_key.pem Закрытый ключ для корневого сертификата X509
mytestrootcert_fullchain.pem Вся ключевая цепочка для корневого сертификата X509.
mytestrootcert.pfx PFX-файл для корневого сертификата X509.
sampleDevice01_cert.pem Общедоступная часть сертификата X509 устройства
sampleDevice01_key.pem Закрытый ключ для сертификата X509 устройства
sampleDevice01_fullchain.pem Вся цепочка ключей для сертификата X509 устройства.
sampleDevice01.pfx PFX-файл для сертификата X509 устройства.

Запишите расположение этих файлов. Он понадобится вам позже.

Создание регистрации группы

  1. Откройте приложение IoT Central и перейдите к разрешениям на панели слева и выберите группы подключений устройств.

  2. Выберите +Создать , чтобы создать новую группу регистрации с именем MyX509Group с типом аттестации сертификатов (X.509). Группы регистрации можно создавать для устройств Интернета вещей или устройств IoT Edge.

  3. В созданной группе регистрации выберите Настроить основное.

  4. На панели "Основной сертификат" выберите "Добавить сертификат".

  5. Отправьте файл корневого сертификата с именем mytestrootcert_cert.pem , созданный ранее.

  6. Если вы используете промежуточный или корневой центр сертификации, которому вы доверяете и знаете, что у вас есть полное владение сертификатом, вы можете самостоятельно проверить, что сертификат проверен, задав состояние сертификата, проверенное при отправке в On. В противном случае задайте состояние сертификата, проверенное при отправке в Off.

  7. Если вы устанавливаете состояние сертификата, проверенное при загрузке, в выкл, выберите "Создать код проверки".

  8. Скопируйте код проверки, скопируйте его и создайте сертификат проверки X.509. Например, в командной строке:

    node create_test_cert.js verification --ca mytestrootcert_cert.pem --key mytestrootcert_key.pem --nonce  {verification-code}
    
  9. Нажмите кнопку "Проверить" , чтобы отправить подписанный сертификат проверки verification_cert.pem , чтобы завершить проверку.

  10. Состояние первичного сертификата теперь проверено:

    Снимок экрана: проверенный сертификат X509.

Теперь вы можете подключить устройства с сертификатом X.509, производным от этого первичного корневого сертификата.

После сохранения группы регистрации запишите область идентификатора. Он понадобится вам позже.

Запуск примера кода устройства

Если вы используете Windows, сертификаты X.509 должны находиться в хранилище сертификатов Windows, чтобы пример работал. В проводнике Windows дважды щелкните на PFX-файлы, созданные ранее — mytestrootcert.pfx и sampleDevice01.pfx. В мастере импорта сертификатов выберите текущего пользователя в качестве расположения хранилища, введите 1234 пароль и позволите мастеру автоматически выбрать хранилище сертификатов. Мастер импортирует сертификаты в личное хранилище текущего пользователя.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. В решении IoTHubDeviceSamples Visual Studio откройте файл Parameter.cs в проекте TemperatureController .

  2. Добавьте в класс следующие два определения параметров:

    [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");
    

    Сохраните изменения.

  3. В решении IoTHubDeviceSamples Visual Studio откройте файл Program.cs в проекте TemperatureController .

  4. Добавьте следующие using инструкции:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Добавьте следующий метод в класс:

    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 в методе case "dps" следующим кодом:

    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. Замените ProvisionDeviceAsync метод следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. Добавьте в проект следующие переменные среды:

    • IOTHUB_DEVICE_X509_CERT: <full path to folder that contains PFX files>sampleDevice01.pfx
    • IOTHUB_DEVICE_X509_PASSWORD: 1234.
  2. Создайте и запустите приложение. Убедитесь, что устройство успешно настроено.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите к папке azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample , которая содержит файл pom.xml и папку src для примера устройства контроллера температуры.

  2. Измените файл pom.xml, чтобы добавить следующую конфигурацию зависимостей в узел <dependencies>.

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

    Сохраните изменения.

  3. Откройте файл src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java в текстовом редакторе.

  4. Замените SecurityProviderSymmetricKey импорт следующими импортами:

    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. Добавьте следующий импорт:

    import java.nio.file.*;
    
  6. Добавьте SecurityProviderException в список исключений, которые main вызывает метод:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Замените initializeAndProvisionDevice метод следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Создайте и запустите приложение. Убедитесь, что устройство успешно настроено.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите к папке azure-iot-sdk-node/device/samples/javascript , содержащей приложение pnp_temperature_controller.js , и выполните следующую команду, чтобы установить пакет X.509:

    npm install azure-iot-security-x509 --save
    
  2. Откройте файлpnp_temperature_controller.js в текстовом редакторе.

  3. Измените инструкции require , чтобы включить следующий код:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Добавьте следующие четыре строки в раздел "Сведения о подключении DPS", чтобы инициализировать deviceCert переменную:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Измените provisionDevice функцию, которая создает клиент, заменив первую строку следующим кодом:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. В той же функции измените строку, которая задает deviceConnectionString переменную следующим образом:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main В функции добавьте следующую строку после строки, которая вызываетClient.fromConnectionString:

    client.setOptions(deviceCert);
    

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Выполните скрипт и убедитесь, что устройство успешно настроено.

    node pnp_temperature_controller.js
    

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите в папку azure-iot-device/samples/pnp и откройте файл temp_controller_with_thermostats.py в текстовом редакторе.

  2. Добавьте следующую from инструкцию для импорта функций X.509:

    from azure.iot.device import X509
    
  3. Измените первую часть provision_device функции следующим образом:

    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 замените строку, которая устанавливает переменную symmetric_key, следующим кодом:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. В функции main замените вызов функции provision_device следующим кодом:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. В функции main замените вызов функции IoTHubDeviceClient.create_from_symmetric_key следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Выполните скрипт и убедитесь, что устройство успешно настроено.

    python temp_controller_with_thermostats.py
    

Убедитесь, что данные телеметрии отображаются в представлении устройства в приложении IoT Central:

Снимок экрана: данные телеметрии с устройства, подключенного с помощью X.509.

Использование отдельной регистрации

Используйте сертификаты X.509 с отдельной регистрацией для тестирования устройства и решения. В рамках индивидуальной регистрации в приложении IoT Central отсутствует корневой или промежуточный сертификат X.509. Устройства используют самозаверяющий сертификат X.509 для подключения к приложению.

Создание самозаверяющего сертификата устройства

В этом разделе вы используете самозаверяющий сертификат X.509 для подключения устройств для отдельной регистрации, которые используются для регистрации одного устройства. Самозаверяющий сертификат используется только для тестирования.

Предупреждение

Этот способ создания сертификатов X.509 предназначен только для тестирования. Для рабочей среды следует использовать официальный безопасный механизм для создания сертификатов.

Создайте самозаверяющий сертификат устройства X.509, выполнив следующие команды:

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

Подсказка

Идентификатор устройства может содержать буквы, цифры и - символ.

Эти команды создают следующие сертификаты устройства:

filename contents
mytestselfcertprimary_cert.pem Общедоступная часть первичного сертификата X509 устройства
mytestselfcertprimary_key.pem Закрытый ключ для сертификата X509 основного устройства
mytestselfcertprimary_fullchain.pem Всю цепочку ключей для первичного сертификата X509 устройства.
mytestselfcertprimary.pfx PFX-файл для сертификата X509 основного устройства.
mytestselfcertsecondary_cert.pem Общедоступная часть сертификата X509 вторичного устройства
mytestselfcertsecondary_key.pem Закрытый ключ для сертификата X509 вторичного устройства
mytestselfcertsecondary_fullchain.pem Вся цепочка ключей для X509 сертификата вторичного устройства.
mytestselfcertsecondary.pfx PFX-файл для сертификата X509 вторичного устройства.

Создание индивидуальной регистрации

  1. В приложении Azure IoT Central выберите "Устройства" и создайте новое устройство с идентификатором устройства в качестве mytestselfcertprimary из шаблона устройства термостата. Запишите область действия ID, чтобы использовать ее позже.

  2. Откройте созданное устройство и нажмите кнопку "Подключить".

  3. Выберите отдельную регистрацию в качестве типа проверки подлинности и сертификатов (X.509) в качестве метода проверки подлинности.

  4. Отправьте файл mytestselfcertprimary_cert.pem , созданный ранее в качестве первичного сертификата.

  5. Отправьте файл mytestselfcertsecondary_cert.pem , созданный ранее в качестве дополнительного сертификата. Затем выберите Сохранить.

  6. Теперь устройство имеет индивидуальную регистрацию с сертификатами X.509.

    Снимок экрана, показывающий, как подключить устройство с помощью индивидуальной регистрации X.509.

Запуск образца устройства для индивидуальной регистрации

Если вы используете Windows, сертификаты X.509 должны находиться в хранилище сертификатов Windows, чтобы пример работал. В проводнике Windows дважды щелкните на PFX-файлы, созданные ранее — mytestselfcertprimary.pfx и mytestselfcertsecondary.pfx. В мастере импорта сертификатов выберите текущего пользователя в качестве расположения хранилища, введите 1234 пароль и позволите мастеру автоматически выбрать хранилище сертификатов. Мастер импортирует сертификаты в личное хранилище текущего пользователя.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. В решении IoTHubDeviceSamples Visual Studio откройте файл Parameter.cs в проекте TemperatureController .

  2. Добавьте в класс следующие два определения параметров:

    [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");
    

    Сохраните изменения.

  3. В решении IoTHubDeviceSamples Visual Studio откройте файл Program.cs в проекте TemperatureController .

  4. Добавьте следующие using инструкции:

    using System.Security.Cryptography.X509Certificates;
    using System.IO;
    
  5. Добавьте следующий метод в класс:

    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 в методе case "dps" следующим кодом:

    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. Замените ProvisionDeviceAsync метод следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. Добавьте в проект следующие переменные среды:

    • 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. Создайте и запустите приложение. Убедитесь, что устройство успешно настроено.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите к папке azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample , которая содержит файл pom.xml и папку src для примера устройства контроллера температуры.

  2. Измените файл pom.xml, чтобы добавить следующую конфигурацию зависимостей в узел <dependencies>.

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

    Сохраните изменения.

  3. Откройте файл src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java в текстовом редакторе.

  4. Замените SecurityProviderSymmetricKey импорт следующими импортами:

    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. Добавьте следующий импорт:

    import java.nio.file.*;
    
  6. Добавьте SecurityProviderException в список исключений, которые main вызывает метод:

    public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
    
  7. Замените initializeAndProvisionDevice метод следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Создайте и запустите приложение. Убедитесь, что устройство успешно настроено.

Вы также можете повторить описанные выше шаги для сертификата mytestselfcertsecondary.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите к папке azure-iot-sdk-node/device/samples/javascript , содержащей приложение pnp_temperature_controller.js , и выполните следующую команду, чтобы установить пакет X.509:

    npm install azure-iot-security-x509 --save
    
  2. Откройте файлpnp_temperature_controller.js в текстовом редакторе.

  3. Измените инструкции require , чтобы включить следующий код:

    const fs = require('fs');
    const X509Security = require('azure-iot-security-x509').X509Security;
    
  4. Добавьте следующие четыре строки в раздел "Сведения о подключении DPS", чтобы инициализировать deviceCert переменную:

    const deviceCert = {
      cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(),
      key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString()
    };
    
  5. Измените provisionDevice функцию, которая создает клиент, заменив первую строку следующим кодом:

    var provSecurityClient = new X509Security(registrationId, deviceCert);
    
  6. В той же функции измените строку, которая задает deviceConnectionString переменную следующим образом:

    deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
    
  7. main В функции добавьте следующую строку после строки, которая вызываетClient.fromConnectionString:

    client.setOptions(deviceCert);
    

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Выполните скрипт и убедитесь, что устройство успешно настроено.

    node pnp_temperature_controller.js
    

Вы также можете повторить описанные выше шаги для сертификата mytestselfcertsecondary.

Чтобы изменить пример кода для использования сертификатов X.509, выполните следующие действия.

  1. Перейдите в папку azure-iot-device/samples/pnp и откройте файл temp_controller_with_thermostats.py в текстовом редакторе.

  2. Добавьте следующую from инструкцию для импорта функций X.509:

    from azure.iot.device import X509
    
  3. Измените первую часть provision_device функции следующим образом:

    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 замените строку, которая устанавливает переменную symmetric_key, следующим кодом:

    x509 = X509(
        cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"),
        key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"),
    )
    
  5. В функции main замените вызов функции provision_device следующим кодом:

    registration_result = await provision_device(
        provisioning_host, id_scope, registration_id, x509, model_id
    )
    
  6. В функции main замените вызов функции IoTHubDeviceClient.create_from_symmetric_key следующим кодом:

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

    Сохраните изменения.

Чтобы запустить пример, выполните следующие действия:

  1. В среде оболочки добавьте следующие две переменные среды. Убедитесь, что вы предоставляете полный путь к PEM-файлам и используете правильный разделитель пути для операционной системы:

    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
    

    Подсказка

    При завершении учебника по созданию и подключению клиентского приложения к приложению Azure IoT Central вы настроили все необходимые переменные среды.

  2. Выполните скрипт и убедитесь, что устройство успешно настроено.

    python temp_controller_with_thermostats.py
    

Вы также можете повторить описанные выше шаги для сертификата mytestselfcertsecondary.

Подключение устройства IoT Edge

В этом разделе предполагается, что вы используете групповую регистрацию для подключения устройства IoT Edge. Выполните действия, описанные в предыдущих разделах, чтобы:

Чтобы подключить устройство IoT Edge к IoT Central с помощью сертификата устройства X.509:

  • Скопируйте сертификаты и файлы ключей устройства на устройство IoT Edge. В предыдущем примере регистрации групп эти файлы назывались sampleDevice01_key.pem и sampleDevice01_cert.pem.

  • На устройстве IoT Edge измените provisioning раздел в файле конфигурации /etc/aziot/config.toml следующим образом:

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

    Подсказка

    Вам не нужно добавлять значение для registration_id. IoT Edge может использовать значение CN из сертификата X.509.

  • Выполните следующую команду, чтобы перезапустить среду выполнения IoT Edge:

    sudo iotedge config apply
    

Дополнительные сведения см. в статье "Создание и подготовка устройств IoT Edge в масштабе на Linux с помощью сертификатов X.509".

Подключение нижестоящего устройства к IoT Edge

IoT Edge использует сертификаты X.509 для защиты подключения между подчиненными устройствами и устройством IoT Edge, действующим в качестве прозрачного шлюза. Дополнительные сведения о настройке этого сценария см. в статье "Подключение нижестоящего устройства к шлюзу Azure IoT Edge".

Свернуть сертификаты устройств X.509

Во время жизненного цикла вашего приложения в IoT Central возможно, потребуется перевыпустить сертификаты X.509. Рассмотрим пример.

  • Если произошло нарушение безопасности, обновление сертификатов — это наилучшая практика для повышения безопасности вашей системы.
  • Сертификаты X.509 имеют даты окончания срока действия. Частота развертывания сертификатов зависит от потребностей безопасности решения. Клиенты с решениями, связанными с высокочувствительными данными, могут ежедневно обновлять сертификаты, в то время как другие обновляют их раз в несколько лет.

Для непрерывного подключения IoT Central позволяет настроить первичные и вторичные сертификаты X.509. Если первичные и вторичные сертификаты имеют разные даты окончания срока действия, можно свернуть сертификат с истекшим сроком действия, пока устройства продолжают подключаться к другому сертификату.

Дополнительные сведения см. в разделе "Методология предполагаемого нарушения" [Microsoft Enterprise Cloud Red Teaming] (https://download.microsoft.com/download/C/1/9/C1990DBA-502F-4C2A-848D-392B93D9B9C3/Microsoft_Enterprise_Cloud_Red_Teaming.pdf).

В этом разделе описывается, как обновить сертификаты в IoT Central. При обновлении сертификата в IoT Central необходимо также скопировать новый сертификат на ваши устройства.

Получение новых сертификатов X.509

Получите новые сертификаты X.509 от поставщика сертификатов. Вы можете создать собственные сертификаты X.509 с помощью средства, например OpenSSL. Этот подход полезен для тестирования сертификатов X.509, но обеспечивает мало гарантий безопасности. Используйте этот подход только для тестирования, если вы не готовы выступать в качестве собственного поставщика ЦС.

Группы регистрации и нарушения безопасности

Чтобы обновить регистрацию группы в ответ на нарушение безопасности, следует использовать следующий подход для немедленного обновления текущего сертификата. Выполните следующие действия для первичных и вторичных сертификатов, если оба сертификата скомпрометируются:

  1. Перейдите к разрешениям в левой области и выберите группы подключений устройств.

  2. Выберите имя группы в списке в разделе "Группы регистрации".

  3. Для обновления сертификата выберите "Управление основным " или " Управление дополнительным".

  4. Добавьте и проверьте корневой сертификат X.509 в группе регистрации.

Отдельные регистрации и нарушения безопасности

Если вы развертываете сертификаты в ответ на нарушение безопасности, используйте следующий подход для немедленного обновления текущего сертификата. Выполните следующие действия для первичных и вторичных сертификатов, если оба этих сертификата скомпрометируются:

  1. Выберите устройства, а затем выберите устройство.

  2. Выберите "Подключиться" и выберите метод подключения в качестве отдельной регистрации

  3. Выберите сертификаты (X.509) в качестве механизма.

  4. Чтобы обновить сертификат, щелкните значок папки, чтобы выбрать новый сертификат, который будет загружен для регистрации. Нажмите кнопку "Сохранить".

Группы регистрации и срок действия сертификата

Чтобы обрабатывать срок действия сертификата, используйте следующий подход для немедленного обновления текущего сертификата:

  1. Перейдите к разрешениям в левой области и выберите группы подключений устройств.

  2. Выберите имя группы в списке в разделе "Группы регистрации".

  3. Для обновления сертификата выберите Управление основным.

  4. Добавьте и проверьте корневой сертификат X.509 в группе регистрации.

  5. Позже, когда срок действия дополнительного сертификата истек, вернитесь и обновите дополнительный сертификат.

Срок действия индивидуальных записей и сертификатов

Если вы регулярно обновляете сертификаты, чтобы управлять истечением срока их действия, следует использовать конфигурацию вторичного сертификата, как показано ниже, для сокращения времени простоя устройств, пытающихся зарегистрироваться в вашем приложении.

Когда срок действия дополнительного сертификата подходит к концу и его необходимо обновить, можно перейти на использование основной конфигурации. Переключение между основными и вторичными сертификатами таким образом сокращает время простоя для устройств, устанавливающих соединение в вашем приложении.

  1. Выберите устройства, а затем выберите устройство.

  2. Выберите "Подключиться" и выберите метод подключения в качестве отдельной регистрации

  3. Выберите сертификаты (X.509) в качестве механизма.

  4. Чтобы обновить вторичный сертификат, щелкните значок папки, чтобы выбрать новый сертификат для записи в реестр. Нажмите кнопку "Сохранить".

  5. Позже, когда срок действия первичного сертификата истекает, вернитесь и обновите первичный сертификат.