Jak połączyć urządzenia z certyfikatami X.509 z aplikacją usługi IoT Central
Usługa IoT Central obsługuje zarówno sygnatury dostępu współdzielonego (SAS) jak i certyfikaty X.509 w celu zabezpieczenia komunikacji między urządzeniem a aplikacją. Samouczek Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central korzysta z sygnatury dostępu współdzielonego. Z tego artykułu dowiesz się, jak zmodyfikować przykładowy kod w celu używania certyfikatów X.509. Certyfikaty X.509 są zalecane w środowiskach produkcyjnych. Aby uzyskać więcej informacji, zobacz Pojęcia dotyczące uwierzytelniania urządzeń.
W tym przewodniku przedstawiono dwa sposoby używania certyfikatów X.509 — rejestracje grupowe zwykle używane w środowisku produkcyjnym oraz rejestracje indywidualne przydatne do testowania. W tym artykule opisano również sposób wprowadzania certyfikatów urządzeń w celu zachowania łączności po wygaśnięciu certyfikatów.
Ten przewodnik opiera się na przykładach przedstawionych w samouczku Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central, które korzystają z języków C#, Java, JavaScript i Python. Aby zapoznać się z przykładem korzystającym z języka programowania C, zobacz Aprowizuj wiele urządzeń X.509 przy użyciu grup rejestracji.
Wymagania wstępne
Aby wykonać kroki opisane w tym przewodniku z instrukcjami, należy najpierw wykonać samouczek Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central. Podczas wykonywania kroków opisanych w tym przewodniku zmodyfikujesz kod użyty w tym samouczku.
W tym przewodniku z instrukcjami wygenerujesz niektóre testowe certyfikaty X.509. Aby móc wygenerować te certyfikaty, potrzebne są następujące elementy:
- Maszyna programistyczna z zainstalowaną Node.js w wersji 6 lub nowszej. Możesz uruchomić
node --version
polecenie w wierszu polecenia, aby sprawdzić swoją wersję. W instrukcjach w tym samouczku założono, że uruchamiasz polecenie node w wierszu polecenia systemu Windows. Można jednak użyć Node.js w wielu innych systemach operacyjnych. - Lokalna kopia zestawu Microsoft Azure IoT SDK dla Node.js repozytorium GitHub zawierająca skrypty służące do generowania testowych certyfikatów X.509. Użyj tego linku, aby pobrać kopię repozytorium: Pobierz plik ZIP. Następnie rozpakuj plik do odpowiedniej lokalizacji na komputerze lokalnym.
Korzystanie z rejestracji grup
Użyj certyfikatów X.509 z rejestracją grupową w środowisku produkcyjnym. W rejestracji grupy do aplikacji usługi IoT Central dodajesz certyfikat główny lub pośredni X.509. Urządzenia z certyfikatami liści pochodzącymi z certyfikatu głównego lub pośredniego mogą łączyć się z aplikacją.
Generowanie certyfikatów głównych i urządzeń
W tej sekcji użyjesz certyfikatu X.509, aby połączyć urządzenie z certyfikatem pochodzącym z certyfikatu grupy rejestracji usługi IoT Central.
Ostrzeżenie
Ten sposób generowania certyfikatów X.509 jest przeznaczony tylko do testowania. W środowisku produkcyjnym należy użyć oficjalnego, bezpiecznego mechanizmu generowania certyfikatów.
Przejdź do skryptu generatora certyfikatów w pobranym zestawie SDK usługi Microsoft Azure IoT dla Node.js. Zainstaluj wymagane pakiety:
cd azure-iot-sdk-node/provisioning/tools npm install
Utwórz certyfikat główny, a następnie utwórz certyfikat urządzenia, uruchamiając skrypt:
node create_test_cert.js root mytestrootcert node create_test_cert.js device sample-device-01 mytestrootcert
Napiwek
Identyfikator urządzenia może zawierać litery, cyfry i
-
znak.
Te polecenia tworzą następujący katalog główny i certyfikaty urządzeń:
filename | Zawartość |
---|---|
mytestrootcert_cert.pem | Publiczna część głównego certyfikatu X509 |
mytestrootcert_key.pem | Klucz prywatny certyfikatu X509 głównego |
mytestrootcert_fullchain.pem | Cały pęk kluczy dla głównego certyfikatu X509. |
mytestrootcert.pfx | Plik PFX certyfikatu X509 głównego. |
sampleDevice01_cert.pem | Publiczna część certyfikatu X509 urządzenia |
sampleDevice01_key.pem | Klucz prywatny certyfikatu X509 urządzenia |
sampleDevice01_fullchain.pem | Cały pęk kluczy dla certyfikatu X509 urządzenia. |
sampleDevice01.pfx | Plik PFX dla certyfikatu X509 urządzenia. |
Zanotuj lokalizację tych plików. Potrzebujesz go później.
Tworzenie rejestracji grupy
Otwórz aplikację usługi IoT Central i przejdź do pozycji Uprawnienia w okienku po lewej stronie i wybierz pozycję Grupy połączeń urządzeń.
Wybierz pozycję + Nowy , aby utworzyć nową grupę rejestracji o nazwie MyX509Group z typem zaświadczania certyfikatów (X.509). Możesz utworzyć grupy rejestracji dla urządzeń IoT lub urządzeń usługi IoT Edge.
W utworzonej grupie rejestracji wybierz pozycję Zarządzaj podstawowym.
W panelu Certyfikat podstawowy wybierz pozycję Dodaj certyfikat.
Przekaż wcześniej wygenerowany plik certyfikatu głównego o nazwie mytestrootcert_cert.pem .
Jeśli używasz pośredniego lub głównego urzędu certyfikacji, któremu ufasz i wiesz, że masz pełną własność certyfikatu, możesz potwierdzić, że zweryfikowano certyfikat, ustawiając stan certyfikatu zweryfikowany podczas przekazywania do pozycji Włączone. W przeciwnym razie ustaw stan certyfikatu zweryfikowany podczas przekazywania na Wyłączone.
Jeśli ustawisz stan certyfikatu zweryfikowany podczas przekazywania do pozycji Wyłączone, wybierz pozycję Generuj kod weryfikacyjny.
Skopiuj kod weryfikacyjny, skopiuj go, a następnie utwórz certyfikat weryfikacji X.509. Na przykład w wierszu polecenia:
node create_test_cert.js verification --ca mytestrootcert_cert.pem --key mytestrootcert_key.pem --nonce {verification-code}
Wybierz pozycję Weryfikuj , aby przekazać podpisany certyfikat weryfikacji verification_cert.pem , aby ukończyć weryfikację.
Stan certyfikatu podstawowego jest teraz zweryfikowany:
Teraz możesz połączyć urządzenia z certyfikatem X.509 pochodzącym z tego podstawowego certyfikatu głównego.
Po zapisaniu grupy rejestracji zanotuj zakres identyfikatorów. Potrzebujesz go później.
Uruchamianie przykładowego kodu urządzenia
Jeśli używasz systemu Windows, certyfikaty X.509 muszą znajdować się w magazynie certyfikatów systemu Windows, aby przykład działał. W Eksploratorze Windows kliknij dwukrotnie wygenerowane wcześniej pliki PFX — mytestrootcert.pfx
i sampleDevice01.pfx
. W Kreatorze importu certyfikatów wybierz pozycję Bieżący użytkownik jako lokalizację magazynu, wprowadź 1234
jako hasło i pozwól kreatorowi automatycznie wybrać magazyn certyfikatów. Kreator importuje certyfikaty do magazynu osobistego bieżącego użytkownika.
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
W rozwiązaniu IoTHubDeviceSamples Visual Studio otwórz plik Parameter.cs w projekcie TemperatureController .
Dodaj następujące dwie definicje parametrów do klasy:
[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");
Zapisz zmiany.
W rozwiązaniu IoTHubDeviceSamples Visual Studio otwórz plik Program.cs w projekcie TemperatureController .
Dodaj następujące instrukcje
using
:using System.Security.Cryptography.X509Certificates; using System.IO;
Dodaj następującą metodę do klasy :
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; }
W metodzie
SetupDeviceClientAsync
zastąp blok kodu następującymcase "dps"
kodem: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;
Zastąp metodę
ProvisionDeviceAsync
poniższym kodem: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); }
Zapisz zmiany.
Aby uruchomić przykład:
Dodaj następujące zmienne środowiskowe do projektu:
IOTHUB_DEVICE_X509_CERT
:<full path to folder that contains PFX files>sampleDevice01.pfx
IOTHUB_DEVICE_X509_PASSWORD
: 1234.
Skompiluj i uruchom aplikację. Sprawdź, czy urządzenie aprowizuje pomyślnie.
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample , który zawiera plik pom.xml i folder src dla przykładu urządzenia kontrolera temperatury.
Edytuj plik pom.xml, aby dodać następującą konfigurację zależności w węźle
<dependencies>
:<dependency> <groupId>com.microsoft.azure.sdk.iot.provisioning.security</groupId> <artifactId>${x509-provider-artifact-id}</artifactId> <version>${x509-provider-version}</version> </dependency>
Zapisz zmiany.
Otwórz plik src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java w edytorze tekstów.
Zastąp
SecurityProviderSymmetricKey
import następującymi importami: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;
Dodaj następujący import:
import java.nio.file.*;
Dodaj
SecurityProviderException
do listy wyjątków zgłaszanych przezmain
metodę:public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
Zastąp metodę
initializeAndProvisionDevice
poniższym kodem: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(); } }
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Skompiluj i uruchom aplikację. Sprawdź, czy urządzenie aprowizuje pomyślnie.
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-sdk-node/device/samples/javascript zawierającego aplikację pnp_temperature_controller.js i uruchom następujące polecenie, aby zainstalować pakiet X.509:
npm install azure-iot-security-x509 --save
Otwórz plik pnp_temperature_controller.js w edytorze tekstów.
Edytuj instrukcje,
require
aby uwzględnić następujący kod:const fs = require('fs'); const X509Security = require('azure-iot-security-x509').X509Security;
Dodaj następujące cztery wiersze do sekcji "Informacje o połączeniu z usługą DPS", aby zainicjować zmienną
deviceCert
:const deviceCert = { cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(), key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString() };
provisionDevice
Edytuj funkcję, która tworzy klienta, zastępując pierwszy wiersz następującym kodem:var provSecurityClient = new X509Security(registrationId, deviceCert);
W tej samej funkcji zmodyfikuj wiersz, który ustawia zmienną
deviceConnectionString
w następujący sposób:deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
main
W funkcji dodaj następujący wiersz po wierszu, który wywołuje polecenieClient.fromConnectionString
:client.setOptions(deviceCert);
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Wykonaj skrypt i sprawdź, czy urządzenie aprowizuje pomyślnie:
node pnp_temperature_controller.js
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-device/samples/pnp i otwórz plik temp_controller_with_thermostats.py w edytorze tekstów.
Dodaj następującą
from
instrukcję, aby zaimportować funkcję X.509:from azure.iot.device import X509
Zmodyfikuj pierwszą część
provision_device
funkcji w następujący sposób: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, )
main
W funkcji zastąp wiersz, który ustawiasymmetric_key
zmienną na następujący kod:x509 = X509( cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"), key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"), )
main
W funkcji zastąp wywołanieprovision_device
funkcji następującym kodem:registration_result = await provision_device( provisioning_host, id_scope, registration_id, x509, model_id )
main
W funkcji zastąp wywołanieIoTHubDeviceClient.create_from_symmetric_key
funkcji następującym kodem: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, )
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Wykonaj skrypt i sprawdź, czy urządzenie aprowizuje pomyślnie:
python temp_controller_with_thermostats.py
Sprawdź, czy dane telemetryczne są wyświetlane w widoku urządzenia w aplikacji usługi IoT Central:
Korzystanie z rejestracji indywidualnej
Użyj certyfikatów X.509 z rejestracją indywidualną, aby przetestować urządzenie i rozwiązanie. W przypadku rejestracji indywidualnej nie ma certyfikatu głównego lub pośredniego X.509 w aplikacji usługi IoT Central. Urządzenia używają certyfikatu X.509 z podpisem własnym w celu nawiązania połączenia z aplikacją.
Generowanie certyfikatu urządzenia z podpisem własnym
W tej sekcji użyjesz certyfikatu X.509 z podpisem własnym do łączenia urządzeń w celu rejestracji indywidualnej, które są używane do rejestrowania pojedynczego urządzenia. Certyfikaty z podpisem własnym są przeznaczone tylko do testowania.
Ostrzeżenie
Ten sposób generowania certyfikatów X.509 jest przeznaczony tylko do testowania. W środowisku produkcyjnym należy użyć oficjalnego, bezpiecznego mechanizmu generowania certyfikatów.
Utwórz certyfikat urządzenia X.509 z podpisem własnym, uruchamiając następujące polecenia:
cd azure-iot-sdk-node/provisioning/tools
node create_test_cert.js device mytestselfcertprimary
node create_test_cert.js device mytestselfcertsecondary
Napiwek
Identyfikator urządzenia może zawierać litery, cyfry i -
znak.
Te polecenia generują następujące certyfikaty urządzeń:
filename | Zawartość |
---|---|
mytestselfcertprimary_cert.pem | Publiczna część certyfikatu X509 urządzenia podstawowego |
mytestselfcertprimary_key.pem | Klucz prywatny certyfikatu X509 urządzenia podstawowego |
mytestselfcertprimary_fullchain.pem | Cały pęk kluczy dla certyfikatu X509 urządzenia podstawowego. |
mytestselfcertprimary.pfx | Plik PFX certyfikatu X509 urządzenia podstawowego. |
mytestselfcertsecondary_cert.pem | Publiczna część certyfikatu X509 urządzenia pomocniczego |
mytestselfcertsecondary_key.pem | Klucz prywatny certyfikatu X509 urządzenia pomocniczego |
mytestselfcertsecondary_fullchain.pem | Cały pęk kluczy dla certyfikatu X509 urządzenia pomocniczego. |
mytestselfcertsecondary.pfx | Plik PFX certyfikatu X509 urządzenia pomocniczego. |
Tworzenie rejestracji indywidualnej
W aplikacji usługi Azure IoT Central wybierz pozycję Urządzenia i utwórz nowe urządzenie z identyfikatorem urządzenia jako mytestselfcertprimary z szablonu urządzenia termostatu. Zanotuj zakres identyfikatorów. Użyj go później.
Otwórz utworzone urządzenie i wybierz pozycję Połączenie.
Wybierz pozycję Rejestracja indywidualna jako typ uwierzytelniania i certyfikaty (X.509) jako metodę uwierzytelniania.
Przekaż plik mytestselfcertprimary_cert.pem wygenerowany wcześniej jako certyfikat podstawowy.
Przekaż plik mytestselfcertsecondary_cert.pem wygenerowany wcześniej jako certyfikat pomocniczy. Następnie wybierz opcję Zapisz.
Urządzenie ma teraz rejestrację indywidualną z certyfikatami X.509.
Uruchamianie przykładowego urządzenia rejestracji indywidualnej
Jeśli używasz systemu Windows, certyfikaty X.509 muszą znajdować się w magazynie certyfikatów systemu Windows, aby przykład działał. W Eksploratorze Windows kliknij dwukrotnie wygenerowane wcześniej pliki PFX — mytestselfcertprimary.pfx
i mytestselfcertsecondary.pfx
. W Kreatorze importu certyfikatów wybierz pozycję Bieżący użytkownik jako lokalizację magazynu, wprowadź 1234
jako hasło i pozwól kreatorowi automatycznie wybrać magazyn certyfikatów. Kreator importuje certyfikaty do magazynu osobistego bieżącego użytkownika.
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
W rozwiązaniu IoTHubDeviceSamples Visual Studio otwórz plik Parameter.cs w projekcie TemperatureController .
Dodaj następujące dwie definicje parametrów do klasy:
[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");
Zapisz zmiany.
W rozwiązaniu IoTHubDeviceSamples Visual Studio otwórz plik Program.cs w projekcie TemperatureController .
Dodaj następujące instrukcje
using
:using System.Security.Cryptography.X509Certificates; using System.IO;
Dodaj następującą metodę do klasy :
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; }
W metodzie
SetupDeviceClientAsync
zastąp blok kodu następującymcase "dps"
kodem: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;
Zastąp metodę
ProvisionDeviceAsync
poniższym kodem: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); }
Zapisz zmiany.
Aby uruchomić przykład:
Dodaj następujące zmienne środowiskowe do projektu:
IOTHUB_DEVICE_DPS_DEVICE_ID
: mytestselfcertprimaryIOTHUB_DEVICE_X509_CERT
:<full path to folder that contains PFX files>mytestselfcertprimary.pfx
IOTHUB_DEVICE_X509_PASSWORD
: 1234.
Skompiluj i uruchom aplikację. Sprawdź, czy urządzenie aprowizuje pomyślnie.
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-sdk-java/device/iot-device-samples/pnp-device-sample/temperature-controller-device-sample , który zawiera plik pom.xml i folder src dla przykładu urządzenia kontrolera temperatury.
Edytuj plik pom.xml, aby dodać następującą konfigurację zależności w węźle
<dependencies>
:<dependency> <groupId>com.microsoft.azure.sdk.iot.provisioning.security</groupId> <artifactId>${x509-provider-artifact-id}</artifactId> <version>${x509-provider-version}</version> </dependency>
Zapisz zmiany.
Otwórz plik src/main/java/samples/com/microsoft/azure/sdk/iot/device/TemperatureController.java w edytorze tekstów.
Zastąp
SecurityProviderSymmetricKey
import następującymi importami: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;
Dodaj następujący import:
import java.nio.file.*;
Dodaj
SecurityProviderException
do listy wyjątków zgłaszanych przezmain
metodę:public static void main(String[] args) throws IOException, URISyntaxException, ProvisioningDeviceClientException, InterruptedException, SecurityProviderException {
Zastąp metodę
initializeAndProvisionDevice
poniższym kodem: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(); } }
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Skompiluj i uruchom aplikację. Sprawdź, czy urządzenie aprowizuje pomyślnie.
Powyższe kroki można również powtórzyć dla certyfikatu mytestselfcertsecondary .
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-sdk-node/device/samples/javascript zawierającego aplikację pnp_temperature_controller.js i uruchom następujące polecenie, aby zainstalować pakiet X.509:
npm install azure-iot-security-x509 --save
Otwórz plik pnp_temperature_controller.js w edytorze tekstów.
Edytuj instrukcje,
require
aby uwzględnić następujący kod:const fs = require('fs'); const X509Security = require('azure-iot-security-x509').X509Security;
Dodaj następujące cztery wiersze do sekcji "Informacje o połączeniu z usługą DPS", aby zainicjować zmienną
deviceCert
:const deviceCert = { cert: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_CERT).toString(), key: fs.readFileSync(process.env.IOTHUB_DEVICE_X509_KEY).toString() };
provisionDevice
Edytuj funkcję, która tworzy klienta, zastępując pierwszy wiersz następującym kodem:var provSecurityClient = new X509Security(registrationId, deviceCert);
W tej samej funkcji zmodyfikuj wiersz, który ustawia zmienną
deviceConnectionString
w następujący sposób:deviceConnectionString = 'HostName=' + result.assignedHub + ';DeviceId=' + result.deviceId + ';x509=true';
main
W funkcji dodaj następujący wiersz po wierszu, który wywołuje polecenieClient.fromConnectionString
:client.setOptions(deviceCert);
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Wykonaj skrypt i sprawdź, czy urządzenie aprowizuje pomyślnie:
node pnp_temperature_controller.js
Powyższe kroki można również powtórzyć dla certyfikatu mytestselfcertsecondary .
Aby zmodyfikować przykładowy kod do używania certyfikatów X.509:
Przejdź do folderu azure-iot-device/samples/pnp i otwórz plik temp_controller_with_thermostats.py w edytorze tekstów.
Dodaj następującą
from
instrukcję, aby zaimportować funkcję X.509:from azure.iot.device import X509
Zmodyfikuj pierwszą część
provision_device
funkcji w następujący sposób: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, )
main
W funkcji zastąp wiersz, który ustawiasymmetric_key
zmienną na następujący kod:x509 = X509( cert_file=os.getenv("IOTHUB_DEVICE_X509_CERT"), key_file=os.getenv("IOTHUB_DEVICE_X509_KEY"), )
main
W funkcji zastąp wywołanieprovision_device
funkcji następującym kodem:registration_result = await provision_device( provisioning_host, id_scope, registration_id, x509, model_id )
main
W funkcji zastąp wywołanieIoTHubDeviceClient.create_from_symmetric_key
funkcji następującym kodem: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, )
Zapisz zmiany.
Aby uruchomić przykład:
W środowisku powłoki dodaj następujące dwie zmienne środowiskowe. Upewnij się, że podasz pełną ścieżkę do plików PEM i użyj odpowiedniego ogranicznika ścieżki dla systemu operacyjnego:
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
Napiwek
Pozostałe wymagane zmienne środowiskowe można ustawić po ukończeniu samouczka Tworzenie i łączenie aplikacji klienckiej z aplikacją usługi Azure IoT Central.
Wykonaj skrypt i sprawdź, czy urządzenie aprowizuje pomyślnie:
python temp_controller_with_thermostats.py
Powyższe kroki można również powtórzyć dla certyfikatu mytestselfcertsecondary .
Łączenie urządzenia usługi IoT Edge
W tej sekcji założono, że używasz rejestracji grupy do łączenia urządzenia usługi IoT Edge. Wykonaj kroki opisane w poprzednich sekcjach, aby:
Aby połączyć urządzenie usługi IoT Edge z usługą IoT Central przy użyciu certyfikatu urządzenia X.509:
Skopiuj certyfikat urządzenia i pliki kluczy na urządzenie usługi IoT Edge. W poprzednim przykładzie rejestracji grupy te pliki były nazywane sampleDevice01_key.pem i sampleDevice01_cert.pem.
Na urządzeniu usługi IoT Edge edytuj
provisioning
sekcję w pliku konfiguracji /etc/aziot/config.toml w następujący sposób:# 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"
Napiwek
Nie musisz dodawać wartości dla elementu
registration_id
. Usługa IoT Edge może użyć wartości CN z certyfikatu X.509.Uruchom następujące polecenie, aby ponownie uruchomić środowisko uruchomieniowe usługi IoT Edge:
sudo iotedge config apply
Aby dowiedzieć się więcej, zobacz Tworzenie i aprowizowanie urządzeń usługi IoT Edge na dużą skalę w systemie Linux przy użyciu certyfikatów X.509.
Połączenie urządzenia podrzędnego do usługi IoT Edge
Usługa IoT Edge używa certyfikatów X.509 do zabezpieczenia połączenia między urządzeniami podrzędnymi a urządzeniem usługi IoT Edge działającym jako przezroczysta brama. Aby dowiedzieć się więcej na temat konfigurowania tego scenariusza, zobacz Połączenie urządzenia podrzędnego do bramy usługi Azure IoT Edge.
Wdrażanie certyfikatów urządzeń X.509
Podczas cyklu życia aplikacji usługi IoT Central może być konieczne wdrożenie certyfikatów X.509. Na przykład:
- W przypadku naruszenia zabezpieczeń certyfikaty stopniowe to najlepsze rozwiązanie w zakresie zabezpieczeń, które pomaga zabezpieczyć system.
- Certyfikaty X.509 mają daty wygaśnięcia. Częstotliwość wprowadzania certyfikatów zależy od potrzeb w zakresie zabezpieczeń rozwiązania. Klienci z rozwiązaniami z udziałem wysoce poufnych danych mogą codziennie wdrażać certyfikaty, podczas gdy inni co kilka lat wdrażają swoje certyfikaty.
W przypadku nieprzerwanej łączności usługa IoT Central umożliwia konfigurowanie certyfikatów podstawowych i pomocniczych X.509. Jeśli certyfikaty podstawowe i pomocnicze mają różne daty wygaśnięcia, możesz przerzucić wygasły certyfikat, podczas gdy urządzenia będą nadal łączyć się z innym certyfikatem.
Aby dowiedzieć się więcej, zobacz Przyjmij metodologię naruszeń.
W tej sekcji opisano sposób wprowadzania certyfikatów w usłudze IoT Central. Podczas wprowadzania certyfikatu w usłudze IoT Central należy również skopiować nowy certyfikat urządzenia na urządzenia.
Uzyskiwanie nowych certyfikatów X.509
Uzyskaj nowe certyfikaty X.509 od dostawcy certyfikatów. Możesz utworzyć własne certyfikaty X.509 przy użyciu narzędzia takiego jak OpenSSL. Takie podejście jest przydatne do testowania certyfikatów X.509, ale zapewnia kilka gwarancji bezpieczeństwa. Tej metody należy używać tylko do testowania, chyba że jesteś przygotowany do działania jako własny dostawca urzędu certyfikacji.
Grupy rejestracji i naruszenia zabezpieczeń
Aby zaktualizować rejestrację grupy w odpowiedzi na naruszenie zabezpieczeń, należy użyć następującego podejścia, aby natychmiast zaktualizować bieżący certyfikat. Wykonaj następujące kroki dla certyfikatów podstawowych i pomocniczych, jeśli oba te certyfikaty zostały naruszone:
Przejdź do pozycji Uprawnienia w okienku po lewej stronie i wybierz pozycję Grupy połączeń urządzeń.
Wybierz nazwę grupy na liście w obszarze Grupy rejestracji.
W przypadku aktualizacji certyfikatu wybierz pozycję Zarządzaj podstawowym lub Zarządzaj pomocniczą.
Dodaj i zweryfikuj główny certyfikat X.509 w grupie rejestracji.
Rejestracje indywidualne i naruszenia zabezpieczeń
Jeśli wdrażasz certyfikaty w odpowiedzi na naruszenie zabezpieczeń, użyj następującego podejścia, aby natychmiast zaktualizować bieżący certyfikat. Wykonaj następujące kroki dla certyfikatów podstawowych i pomocniczych, jeśli oba te certyfikaty zostały naruszone:
Wybierz pozycję Urządzenia i wybierz urządzenie.
Wybierz pozycję Połączenie i wybierz metodę połącz jako Rejestrację indywidualną
Wybierz pozycję Certyfikaty (X.509) jako mechanizm.
W przypadku aktualizacji certyfikatu wybierz ikonę folderu, aby wybrać nowy certyfikat do przekazania dla wpisu rejestracji. Wybierz pozycję Zapisz.
Grupy rejestracji i wygaśnięcie certyfikatu
Aby obsłużyć wygasanie certyfikatu, użyj następującego podejścia, aby natychmiast zaktualizować bieżący certyfikat:
Przejdź do pozycji Uprawnienia w okienku po lewej stronie i wybierz pozycję Grupy połączeń urządzeń.
Wybierz nazwę grupy na liście w obszarze Grupy rejestracji.
W przypadku aktualizacji certyfikatu wybierz pozycję Zarządzaj podstawowym.
Dodaj i zweryfikuj główny certyfikat X.509 w grupie rejestracji.
Później po wygaśnięciu certyfikatu pomocniczego wróć i zaktualizuj certyfikat pomocniczy.
Rejestracje indywidualne i wygaśnięcie certyfikatu
Jeśli wdrażasz certyfikaty do obsługi wygasania certyfikatów, należy użyć konfiguracji certyfikatu pomocniczego w następujący sposób, aby zmniejszyć czas przestoju dla urządzeń próbujących aprowizować w aplikacji.
Gdy certyfikat pomocniczy zbliża się do wygaśnięcia i musi zostać wycofany, można dokonać rotacji w celu użycia konfiguracji podstawowej. Rotacja między certyfikatami podstawowymi i pomocniczymi w ten sposób zmniejsza przestoje urządzeń próbujących aprowizować w aplikacji.
Wybierz pozycję Urządzenia i wybierz urządzenie.
Wybierz pozycję Połączenie i wybierz metodę połącz jako Rejestrację indywidualną
Wybierz pozycję Certyfikaty (X.509) jako mechanizm.
W przypadku aktualizacji certyfikatu pomocniczego wybierz ikonę folderu, aby wybrać nowy certyfikat do przekazania dla wpisu rejestracji. Wybierz pozycję Zapisz.
Później, gdy certyfikat podstawowy wygasł, wróć i zaktualizuj certyfikat podstawowy.