프로그래밍 방식으로 X.509 인증서 증명을 위해 Device Provisioning Service 등록 그룹 만들기

이 문서에서는 중간 또는 루트 CA X.509 인증서를 사용하는 등록 그룹을 프로그래밍 방식으로 만드는 방법을 보여 줍니다. 등록 그룹은 Azure IoT Hub DPS 서비스 SDK 및 샘플 애플리케이션을 사용하여 만듭니다. 등록 그룹은 해당 인증서 체인에 일반적인 서명 인증서를 공유하는 디바이스의 프로비전 서비스에 대한 액세스를 제어합니다. 자세히 알아보려면 X.509 인증서를 사용하여 프로비전 서비스에 대한 디바이스 액세스 제어를 참조하세요. Azure IoT Hub 및 Device Provisioning Service에서 X.509 인증서 기반 PKI(공개 키 인프라)를 사용하는 방법에 대한 자세한 내용은 X.509 CA 인증서 보안 개요를 참조하세요.

필수 조건

  • Windows 기반 컴퓨터에 .NET 6.0 SDK 이상 이상을 설치합니다. 다음 명령을 사용하여 버전을 확인할 수 있습니다.

    dotnet --info
    
  • 최신 버전의 Git을 설치합니다. Git이 명령 창에 액세스할 수 있는 환경 변수에 추가되었는지 확인합니다. 설치할 git 도구의 최신 버전은 Software Freedom Conservancy의 Git 클라이언트 도구를 참조하세요. 여기에는 로컬 Git 리포지토리와 상호 작용하는 데 사용할 수 있는 명령줄 앱인 Git Bash가 포함됩니다.

참고 항목

이 문서의 단계는 Windows 및 Linux 컴퓨터 모두에서 작동하지만, 이 문서에서는 Windows 개발 컴퓨터를 사용합니다.

테스트 인증서 만들기

X.509 인증서 증명을 사용하는 등록 그룹은 루트 CA 인증서 또는 중간 인증서를 사용하도록 구성할 수 있습니다. 더 일반적인 경우는 중간 인증서를 사용하여 등록 그룹을 구성하는 것입니다. 중간 인증서를 사용하면 동일한 루트 CA 인증서에서 여러 중간 인증서를 생성하거나 해지할 수 있으므로 더 많은 유연성을 제공합니다.

이 문서에서는 루트 CA 인증서 파일, 중간 CA 인증서 파일 또는 .pem 또는 .cer 형식이 모두 필요합니다. 한 파일에는 루트 CA X.509 인증서의 공용 부분이 포함되고 다른 파일에는 중간 CA X.509 인증서의 공용 부분이 포함됩니다.

루트 CA 파일 및/또는 중간 CA 파일이 이미 있는 경우 루트 또는 중간 CA 인증서를 계속 추가하고 확인할 수 있습니다.

루트 CA 파일 및/또는 중간 CA 파일이 없는 경우 X.509 인증서 체인 만들기의 단계에 따라 만듭니다. 이 문서의 단계를 완료하는 데 디바이스 인증서가 필요하지 않으므로 중간 CA 인증서 만들기의 단계를 완료한 후 중지할 수 있습니다. 완료되면 ./certs/azure-iot-test-only.root.ca.cert.pem./certs/azure-iot-test-only.intermediate.cert.pem이라는 두 개의 X.509 인증서 파일이 만들어집니다.

루트 또는 중간 CA 인증서 추가 및 확인

X.509 인증서를 사용하여 등록 그룹을 통해 프로비저닝하는 디바이스는 DPS로 인증할 때 전체 인증서 체인을 제공합니다. DPS는 인증서 체인을 확인할 수 있어야 하므로 등록 그룹에서 구성된 루트 또는 중간 인증서는 확인된 인증서여야 하거나 서비스에 인증할 때 디바이스가 나타내는 인증서 체인에서 확인된 인증서로 롤업되어야 합니다.

이 문서에서는 루트 CA 인증서와 루트 CA에서 서명한 중간 CA 인증서가 모두 있다고 가정합니다.

  • 루트 CA 인증서를 사용하여 등록 그룹을 만들려는 경우 루트 CA 인증서를 업로드하고 확인해야 합니다.

  • 중간 CA 인증서를 사용하여 등록 그룹을 만들려는 경우 루트 CA 인증서 또는 중간 CA 인증서를 업로드하고 확인하면 됩니다. (인증서 체인에 여러 중간 CA 인증서가 있는 경우 루트 CA 인증서와 등록 그룹을 만드는 중간 인증서 사이에 있는 중간 인증서를 업로드하고 확인할 수 있습니다.)

Device Provisioning Service에 루트 또는 중간 CA 인증서를 추가하고 확인하려면 다음을 수행합니다.

  1. Azure Portal에 로그인합니다.

  2. 왼쪽 메뉴 또는 포털 페이지에서 모든 리소스를 선택합니다.

  3. Device Provisioning Service를 선택합니다.

  4. 설정 메뉴에서 인증서를 선택합니다.

  5. 위쪽 메뉴에서 + 추가:를 선택합니다.

  6. 루트 또는 중간 CA 인증서의 이름을 입력하고 .pem 또는 .cer 파일을 업로드합니다.

  7. 업로드 시 인증서 상태를 확인하도록 설정을 선택합니다.

    Screenshot that shows adding the root CA certificate to a DPS instance.

  8. 저장을 선택합니다.

프로비전 서비스에 대한 연결 문자열 가져오기

이 문서의 샘플에서는 프로비전 서비스에 대한 연결 문자열이 필요합니다. 다음 단계에 따라 검색합니다.

  1. Azure Portal에 로그인합니다.

  2. 왼쪽 메뉴 또는 포털 페이지에서 모든 리소스를 선택합니다.

  3. Device Provisioning Service를 선택합니다.

  4. 설정 메뉴에서 공유 액세스 정책을 선택합니다.

  5. 사용하려는 액세스 정책을 선택합니다.

  6. 액세스 정책 패널에서 기본 키 연결 문자열을 복사하여 저장합니다.

    Screenshot that shows the location of the provisioning service connection string in the portal.

등록 그룹 샘플 만들기

이 섹션에서는 등록 그룹을 프로비전 서비스에 추가하는 .NET Core 콘솔 애플리케이션을 만드는 방법을 보여줍니다.

  1. Windows 명령 프롬프트를 열고 앱을 만들려는 폴더로 이동합니다.

  2. 콘솔 프로젝트를 만들려면 다음 명령을 실행합니다.

    dotnet new console --framework net6.0 --use-program-main 
    
  3. DPS 서비스 SDK에 대한 참조를 추가하려면 다음 명령을 실행합니다.

    dotnet add package Microsoft.Azure.Devices.Provisioning.Service 
    

    이 단계에서는 Azure IoT DPS 서비스 클라이언트 NuGet 패키지 및 종속 항목에 대한 참조를 다운로드, 설치 및 추가합니다. 이 패키지에는 .NET 서비스 SDK용 이진 파일이 포함되어 있습니다.

  4. 편집기에서 Program.cs 파일을 엽니다.

  5. 파일 맨 위에 있는 네임스페이스 문을 다음 줄로 바꿉니다.

    namespace CreateEnrollmentGroup;
    
  6. namespace위의 파일 상단에 다음 using 문을 추가합니다.

    using System.Security.Cryptography.X509Certificates;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Provisioning.Service;
    
  7. Program 클래스에 다음 필드를 추가하고 표시된 변경 작업을 수행합니다.

    private static string ProvisioningConnectionString = "{ProvisioningServiceConnectionString}";
    private static string EnrollmentGroupId = "enrollmentgrouptest";
    private static string X509RootCertPath = @"{Path to a .cer or .pem file for a verified root CA or intermediate CA X.509 certificate}";
    
    • ProvisioningServiceConnectionString 자리 표시자 값을 이전 섹션에서 복사한 프로비전 서비스의 연결 문자열로 바꿉니다.

    • X509RootCertPath 자리 표시자 값을 .pem 또는 .cer 파일의 경로로 바꿉니다. 이 파일은 이전에 프로비저닝 서비스에서 업로드되고 확인된 루트 CA X.509 인증서 또는 자체적으로 업로드하고 확인되었거나 서명 체인에 인증서가 업로드되고 확인된 중간 인증서의 공개 부분을 나타냅니다.

    • 필요에 따라 EnrollmentGroupId 값을 변경할 수 있습니다. 문자열에는 소문자 및 하이픈만 포함될 수 있습니다.

    Important

    프로덕션 코드에서는 다음 보안 고려 사항을 고려해야 합니다.

    • 프로비전 서비스 관리자에 대한 연결 문자열을 하드 코딩하면 보안 모범 사례에 반합니다. 대신 연결 문자열은 보안 구성 파일 또는 레지스트리에서와 같이 안전하게 유지되어야 합니다.
    • 서명 인증서의 공용 부분만 업로드해야 합니다. 프라이빗 키를 포함하는 .pfx(PKCS12) 또는 .pem 파일을 프로비전 서비스에 업로드하지 않습니다.
  8. 다음 메서드를 Program 클래스에 추가합니다. 이 코드는 EnrollmentGroup 항목을 만든 다음, ProvisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync 메서드를 호출하여 프로비저닝 서비스에 등록 그룹을 추가합니다.

    public static async Task RunSample()
    {
        Console.WriteLine("Starting sample...");
    
        using (ProvisioningServiceClient provisioningServiceClient =
                ProvisioningServiceClient.CreateFromConnectionString(ProvisioningConnectionString))
        {
            #region Create a new enrollmentGroup config
            Console.WriteLine("\nCreating a new enrollmentGroup...");
            var certificate = new X509Certificate2(X509RootCertPath);
            Attestation attestation = X509Attestation.CreateFromRootCertificates(certificate);
            EnrollmentGroup enrollmentGroup =
                    new EnrollmentGroup(
                            EnrollmentGroupId,
                            attestation)
                    {
                        ProvisioningStatus = ProvisioningStatus.Enabled
                    };
            Console.WriteLine(enrollmentGroup);
            #endregion
    
            #region Create the enrollmentGroup
            Console.WriteLine("\nAdding new enrollmentGroup...");
            EnrollmentGroup enrollmentGroupResult =
                await provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(enrollmentGroup).ConfigureAwait(false);
            Console.WriteLine("\nEnrollmentGroup created with success.");
            Console.WriteLine(enrollmentGroupResult);
            #endregion
    
        }
    }
    
  9. 마지막으로 Main 메서드를 다음 줄로 바꿉니다.

    static async Task Main(string[] args)
    {
        await RunSample();
        Console.WriteLine("\nHit <Enter> to exit ...");
        Console.ReadLine();
    }
    
  10. 변경 내용을 저장합니다.

이 섹션에서는 등록 그룹을 프로비저닝 서비스에 추가하는 node.js 스크립트를 만드는 방법을 보여 줍니다.

  1. 작업 폴더의 명령 창에서 다음을 실행합니다.

    npm install azure-iot-provisioning-service
    

    이 단계에서는 Azure IoT DPS 서비스 클라이언트 패키지 및 종속 항목에 대한 참조를 다운로드, 설치 및 추가합니다. 이 패키지에는 Node.js 서비스 SDK용 이진 파일이 포함되어 있습니다.

  2. 텍스트 편집기를 사용하여 작업 폴더에 create_enrollment_group.js 파일을 만듭니다. 다음 코드를 파일에 추가하고 저장합니다.

        'use strict';
        var fs = require('fs');
    
        var provisioningServiceClient = require('azure-iot-provisioning-service').ProvisioningServiceClient;
    
        var serviceClient = provisioningServiceClient.fromConnectionString(process.argv[2]);
    
        var enrollment = {
          enrollmentGroupId: 'first',
          attestation: {
            type: 'x509',
            x509: {
              signingCertificates: {
                primary: {
                  certificate: fs.readFileSync(process.argv[3], 'utf-8').toString()
                }
              }
            }
          },
          provisioningStatus: 'disabled'
        };
    
        serviceClient.createOrUpdateEnrollmentGroup(enrollment, function(err, enrollmentResponse) {
          if (err) {
            console.log('error creating the group enrollment: ' + err);
          } else {
            console.log("enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2));
            enrollmentResponse.provisioningStatus = 'enabled';
            serviceClient.createOrUpdateEnrollmentGroup(enrollmentResponse, function(err, enrollmentResponse) {
              if (err) {
                console.log('error updating the group enrollment: ' + err);
              } else {
                console.log("updated enrollment record returned: " + JSON.stringify(enrollmentResponse, null, 2));
              }
            });
          }
        });
    

  1. Windows 명령 프롬프트를 엽니다.

  2. Java 서비스 SDK를 사용하여 디바이스 등록 코드 샘플에 대한 GitHub 리포지토리를 복제합니다.

    git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
    
  3. 리포지토리를 다운로드한 위치에서 샘플 폴더로 이동합니다.

    cd azure-iot-sdk-java\provisioning\provisioning-service-client-samples\service-enrollment-group-sample 
    
  4. 원하는 편집기에서 /src/main/java/samples/com/microsoft/azure/sdk/iot/ServiceEnrollmentGroupSample.java 파일을 엽니다.

  5. [Provisioning Connection String]프로비전 서비스에 대한 연결 문자열 가져오기에서 복사한 연결 문자열로 바꿉니다.

  6. PUBLIC_KEY_CERTIFICATE_STRING 상수 문자열을 루트 또는 중간 CA 인증서 .pem 파일의 값으로 바꿉니다. 이 파일은 이전에 프로비저닝 서비스에서 업로드되고 확인된 루트 CA X.509 인증서 또는 자체적으로 업로드하고 확인되었거나 서명 체인에 인증서가 업로드되고 확인된 중간 인증서의 공개 부분을 나타냅니다.

    인증서 텍스트 구문은 추가 공백이나 문자 없이 아래 패턴을 따라야 합니다.

    private static final String PUBLIC_KEY_CERTIFICATE_STRING = 
            "-----BEGIN CERTIFICATE-----\n" +
            "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n" +
                ...
            "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n" +
            "-----END CERTIFICATE-----";
    

    이 문자열 값을 수동으로 업데이트하면 오류가 발생하기 쉽습니다. 적절한 구문을 생성하려면 다음 명령을 복사하여 Git Bash 프롬프트에 붙여넣고 your-cert.pem을 인증서 파일의 위치로 바꾸고 Enter 키를 누릅니다. 이 명령은 PUBLIC_KEY_CERTIFICATE_STRING 문자열 상수 값에 대한 구문을 생성하고 출력에 씁니다.

    sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' your-cert.pem
    

    상수 값에 대한 출력 인증서 텍스트를 복사하여 붙여넣습니다.

    Important

    프로덕션 코드에서는 다음 보안 고려 사항을 고려해야 합니다.

    • 프로비전 서비스 관리자에 대한 연결 문자열을 하드 코딩하면 보안 모범 사례에 반합니다. 대신 연결 문자열은 보안 구성 파일 또는 레지스트리에서와 같이 안전하게 유지되어야 합니다.
    • 서명 인증서의 공용 부분만 업로드해야 합니다. 프라이빗 키를 포함하는 .pfx(PKCS12) 또는 .pem 파일을 프로비전 서비스에 업로드하지 않습니다.
  7. 이 샘플을 사용하면 등록 그룹에서 디바이스를 프로비저닝할 IoT Hub를 설정할 수 있습니다. 이전에 프로비저닝 서비스에 연결된 IoT 허브여야 합니다. 이 문서에서는 DPS가 기본 할당 정책인 균등 가중치 배포에 따라 연결된 허브에서 선택하도록 합니다. 파일에서 다음 문을 주석으로 처리합니다.

    enrollmentGroup.setIotHubHostName(IOTHUB_HOST_NAME);                // Optional parameter.
    
  8. 샘플 코드는 X.509 디바이스에 대한 등록 그룹을 만들고, 업데이트하고, 쿼리하고, 삭제합니다. Azure Portal에 등록 그룹을 만들었는지 확인하려면 파일 끝 주변에 다음 코드 줄을 일시적으로 주석으로 처리합니다.

    // ************************************** Delete info of enrollmentGroup ***************************************
    System.out.println("\nDelete the enrollmentGroup...");
    provisioningServiceClient.deleteEnrollmentGroup(enrollmentGroupId);
    
  9. ServiceEnrollmentGroupSample.java 파일을 저장합니다.

등록 그룹 샘플 실행

  1. 샘플을 실행합니다.

    dotnet run
    
  2. 성공적으로 만들어지면 명령 창에 새 등록 그룹에 대한 속성이 표시됩니다.

  1. 명령 프롬프트에서 다음 명령을 실행합니다. 명령 인수를 따옴표로 묶고, <connection string>을 이전 섹션에서 복사한 연결 문자열로 바꾸고, <certificate .pem file>을 인증서 .pem 파일의 경로로 바꿔야 합니다. 이 파일은 이전에 프로비저닝 서비스에서 업로드되고 확인된 루트 CA X.509 인증서 또는 자체적으로 업로드하고 확인되었거나 서명 체인에 인증서가 업로드되고 확인된 중간 인증서의 공개 부분을 나타냅니다.

    node create_enrollment_group.js "<connection string>" "<certificate .pem file>"
    
  2. 성공적으로 만들어지면 명령 창에 새 등록 그룹에 대한 속성이 표시됩니다.

  1. 명령 프롬프트의 azure-iot-sdk-java\provisioning\provisioning-service-client-samples\service-enrollment-group-sample 폴더에서 다음 명령을 실행하여 샘플을 빌드합니다.

    mvn install -DskipTests
    

    이 명령은 Azure IoT DPS 서비스 클라이언트 Maven 패키지를 컴퓨터에 다운로드하고 샘플을 빌드합니다. 이 패키지에는 Java 서비스 SDK용 이진 파일이 포함되어 있습니다.

  2. target 폴더로 전환하고 샘플을 실행합니다. 이전 단계의 빌드는 provisioning-x509-sample-{version}-with-deps.jar 파일 형식으로 target 폴더에 .jar 파일을 출력합니다(예: provisioning-x509-sample-1.8.1-with-deps.jar). 아래 명령에서 버전을 바꿔야 할 수도 있습니다.

    cd target
    java -jar ./service-enrollment-group-sample-1.8.1-with-deps.jar
    
  3. 성공적으로 만들어지면 명령 창에 새 등록 그룹에 대한 속성이 표시됩니다.

등록 그룹이 만들어졌는지 확인하려면 다음을 수행합니다.

  1. Azure Portal에서 Device Provisioning Service 인스턴스로 이동합니다.

  2. 설정 메뉴에서 등록 관리를 선택합니다.

  3. 등록 그룹 탭을 선택합니다. 샘플에서 사용한 등록 그룹 ID에 해당하는 새 등록 항목이 표시됩니다.

Screenshot that shows the newly created enrollment group in the portal.

Screenshot that shows the newly created enrollment group in the portal.

Screenshot that shows the newly created enrollment group in the portal.

리소스 정리

Azure IoT Hub Device Provisioning Service 자습서를 살펴보려면 이 문서에서 만든 리소스를 정리하지 마세요. 그렇지 않으면 다음 단계에서 이 문서에서 만든 모든 리소스를 삭제합니다.

  1. 컴퓨터에서 샘플 출력 창을 닫습니다.

  2. Azure Portal의 왼쪽 메뉴에서 모든 리소스를 선택합니다.

  3. Device Provisioning Service를 선택합니다.

  4. 설정 아래 왼쪽 메뉴에서 등록 관리를 선택합니다.

  5. 등록 그룹 탭을 선택합니다.

  6. 이 문서에서 만든 등록 그룹의 그룹 이름 옆에 있는 확인란을 선택합니다.

  7. 페이지 위쪽에서 삭제를 선택합니다.

  8. Azure Portal의 Device Provisioning Service에서 왼쪽 메뉴의 설정 아래에서 인증서를 선택합니다.

  9. 이 문서를 진행하기 위해 업로드한 인증서를 선택합니다.

  10. 인증서 세부 정보의 위쪽에서 삭제를 선택합니다.

인증서 도구

Azure IoT C SDK에는 Azure 리소스를 만들고 관리하는 데 도움이 되는 스크립트가 있습니다. 자세한 내용은 샘플 및 자습서에 대한 테스트 CA 인증서 관리를 참조하세요.

Azure IoT Node.js SDK에는 Azure 리소스를 만들고 관리하는 데 도움이 되는 스크립트가 있습니다. 자세한 내용은 Node.jsNode.js에 대한 Azure IoT 디바이스 프로비저닝 디바이스 SDK용 도구를 참조하세요.

Azure IoT C SDK에서 사용할 수 있는 도구를 사용할 수도 있습니다. 자세한 내용은 샘플 및 자습서에 대한 테스트 CA 인증서 관리를 참조하세요.

Azure IoT Java SDK에는 인증서를 만들고 관리하는 데 도움이 되는 테스트 도구가 포함되어 있습니다. 자세한 내용은 DICE 에뮬레이터를 사용하는 X509 인증서 생성기를 참조하세요.

다음 단계

이 문서에서는 Azure IoT Hub Device Provisioning Service를 사용하여 X.509 중간 또는 루트 CA 인증서에 대한 등록 그룹을 만들었습니다. 더 자세히 알아보려면 다음 링크를 확인합니다.