자습서: 등록 그룹을 사용하여 여러 X.509 디바이스 프로비저닝

이 자습서에서는 X.509 인증서를 인증에 사용하는 IoT 디바이스 그룹을 프로비저닝하는 방법을 알아봅니다. Azure IoT SDK의 샘플 디바이스 코드는 개발 컴퓨터에서 실행되어 X.509 디바이스의 프로비저닝을 시뮬레이션합니다. 실제 디바이스에서 디바이스 코드는 IoT 디바이스에서 배포되고 실행됩니다.

Azure IoT Hub Device Provisioning Service는 디바이스 프로비저닝에 대해 다음 두 가지 유형의 등록을 지원합니다.

  • 등록 그룹: 여러 관련 디바이스를 등록하는 데 사용됩니다. 이 자습서에서는 등록 그룹을 사용하여 프로비저닝하는 방법을 보여 줍니다.
  • 개별 등록: 단일 디바이스를 등록하는 데 사용됩니다.

Azure IoT Hub Device Provisioning Service는 디바이스 프로비저닝에 대해 다음 세 가지 유형의 인증을 지원합니다.

  • X.509 인증서 - 이 자습서에서는 X.509 인증서 증명을 보여 줍니다.
  • 신뢰할 수 있는 플랫폼 모듈(TPM)
  • 대칭 키

프로덕션 시나리오 에서 HSM(하드웨어 보안 모듈) 은 디바이스 비밀의 안전한 하드웨어 기반 스토리지에 사용됩니다. HSM은 대칭 키, X.509 인증서 또는 TPM 증명에 사용하여 비밀을 안전하게 저장할 수 있습니다. 디바이스 비밀의 하드웨어 기반 스토리지는 디바이스 인증서의 프라이빗 키와 같은 중요한 정보를 보호하는 데 도움이 되는 것이 좋습니다.

이 자습서에서는 다음 목표를 달성합니다.

  • X.509 인증서를 사용하여 디바이스 세트를 구성하는 신뢰 인증서 체인 만들기
  • 인증서 체인을 사용하는 새 그룹 등록 만들기.
  • 개발 환경 설정.
  • Azure IoT 디바이스 SDK에서 샘플 코드를 사용하여 인증서 체인을 사용하여 디바이스를 프로비전합니다.

필수 조건

디바이스를 시뮬레이션하는 데 사용되는 Windows 개발 환경에 대한 필수 구성 요소는 다음과 같습니다. Linux 또는 macOS의 경우 SDK 설명서에서 개발 환경 준비의 해당 섹션을 참조하세요.

  • Visual Studio 2022를 설치하고 'C++를 사용한 데스크톱 개발' 워크로드를 사용하도록 설정합니다. Visual Studio 2015, Visual Studio 2017 및 Visual Studio 19도 지원됩니다.

  • 최신 CMake 빌드 시스템을 설치합니다. CMake 실행 파일을 경로에 추가하는 옵션을 선택했는지 확인합니다.

    Important

    설치를 시작하기 CMake 전에 Visual Studio 필수 구성 요소(Visual Studio 및 'C++를 사용한 데스크톱 개발' 워크로드)가 컴퓨터에 설치되어 있는지 확인합니다. 필수 구성 요소가 설치되고 다운로드를 확인하면 CMake 빌드 시스템을 설치합니다. 이전 버전의 CMake 빌드 시스템은 이 자습서에 사용된 솔루션 파일을 생성하지 못합니다. 최신 버전의 CMake를 사용해야 합니다.

다음 필수 구성 요소는 Windows 개발 환경을 위한 것입니다. Linux 또는 macOS의 경우 SDK 설명서에서 개발 환경 준비의 해당 섹션을 참조하세요.

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

    dotnet --info
    

다음 필수 구성 요소는 Windows 개발 환경을 위한 것입니다. Linux 또는 macOS의 경우 SDK 설명서에서 개발 환경 준비의 해당 섹션을 참조하세요.

다음 필수 구성 요소는 Windows 개발 환경을 위한 것입니다.

다음 필수 구성 요소는 Windows 개발 환경을 위한 것입니다. Linux 또는 macOS의 경우 SDK 설명서에서 개발 환경 준비의 해당 섹션을 참조하세요.

  • 최신 버전의 Git을 설치합니다. Git이 명령 창에 액세스할 수 있는 환경 변수에 추가되었는지 확인합니다.

  • OpenSSL컴퓨터에 설치되어 있는지 확인합니다. Windows에서 Git 설치에는 OpenSSL 설치가 포함됩니다. Git Bash 프롬프트에서 OpenSSL에 액세스할 수 있습니다. OpenSSL이 설치되었는지 확인하려면 Git Bash 프롬프트를 열고 openssl version을 입력합니다.

    참고 항목

    OpenSSL에 익숙하지 않고 Windows 컴퓨터에 이미 설치되어 있지 않은 경우 Git Bash 프롬프트에서 OpenSSL을 사용하는 것이 좋습니다. 또는 소스 코드를 다운로드하고 OpenSSL을 빌드하도록 선택할 수 있습니다. OpenSSL을 빌드하거나 다운로드하기로 선택한 경우 경로에서 OpenSSL 이진 파일에 액세스할 수 있고 OPENSSL_CNF 환경 변수가 openssl.cnf 파일의 경로로 설정되어 있는지 확인합니다.

개발 환경 준비

이 섹션에서는 Azure IoT C SDK를 빌드하는 데 사용되는 개발 환경을 준비합니다. 이 SDK는 DPS에서 디바이스 프로비저닝에 사용하는 샘플 코드 및 도구를 포함하고 있습니다.

  1. 웹 브라우저에서 Azure IoT C SDK의 릴리스 페이지로 이동합니다.

  2. Azure IoT C SDK의 최신 릴리스에 대한 태그 이름을 복사합니다(예: lts_03_2024.

  3. Windows 명령 프롬프트를 열고 다음 명령을 실행하여 C GitHub 리포지토리용 Azure IoT 디바이스 SDK의 최신 릴리스를 복제합니다. 이전 단계에서 복사한 태그로 바꿉 <release-tag> 습니다.

    git clone -b <release-tag> https://github.com/Azure/azure-iot-sdk-c.git
    cd azure-iot-sdk-c
    git submodule update --init
    

    이 작업을 완료하는 데 몇 분 정도 걸릴 수 있습니다.

  4. 작업이 완료되면 azure-iot-sdk-c 디렉터리에서 다음 명령을 실행합니다.

    mkdir cmake
    cd cmake
    
  5. 코드 샘플에서는 X.509 인증서를 사용하여 X.509 인증을 통해 증명을 제공합니다. 다음 명령을 실행하여 디바이스 프로비저닝 클라이언트를 포함하는 개발 플랫폼과 관련된 SDK 버전을 빌드합니다. 시뮬레이션된 디바이스에 대한 Visual Studio 솔루션이 cmake 디렉터리에서 생성됩니다.

    복제한 C SDK의 절대 경로로 바꿉 <path 다.

    cmake -Duse_prov_client:BOOL=ON -Dhsm_custom_lib=c:/<path>/azure-iot-sdk-c/cmake/provisioning_client/samples/custom_hsm_example/Debug/custom_hsm_example.lib ..
    

    cmake이(가) C++ 컴파일러를 찾지 못하면 위의 명령을 실행하는 동안 빌드 오류가 발생할 수 있습니다. 이 경우에는 Visual Studio 명령 프롬프트에서 명령을 실행합니다.

  6. 빌드가 성공되면 마지막 몇 개의 출력 줄은 다음 출력과 유사하게 표시됩니다.

    cmake -Duse_prov_client:BOOL=ON -Dhsm_custom_lib=c:/azure-iot-sdk-c/cmake/provisioning_client/samples/custom_hsm_example/Debug/custom_hsm_example.lib ..
    -- Building for: Visual Studio 17 2022
    -- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.22000.
    -- The C compiler identification is MSVC 19.32.31329.0
    -- The CXX compiler identification is MSVC 19.32.31329.0
    
    ...
    
    -- Configuring done
    -- Generating done
    -- Build files have been written to: C:/azure-iot-sdk-c/cmake
    

Windows 명령 프롬프트를 열고 다음 명령을 사용하여 C# GitHub 리포지토리용 Azure IoT SDK를 복제합니다.

git clone https://github.com/Azure/azure-iot-sdk-csharp.git

Windows 명령 프롬프트를 열고 다음 명령을 사용하여 Node.js GitHub 리포지토리용 Azure IoT SDK를 복제합니다.

git clone https://github.com/Azure/azure-iot-sdk-node.git

Windows 명령 프롬프트를 열고 다음 명령을 사용하여 Python GitHub 리포지토리용 Azure IoT 디바이스 SDK를 복제합니다.

git clone -b v2 https://github.com/Azure/azure-iot-sdk-python.git --recursive

참고 항목

이 자습서에 사용된 샘플은 azure-iot-sdk-python 리포지토리의 v2 분기에 있습니다. Python SDK의 V3는 베타에서 사용할 수 있습니다.

  1. Windows 명령 프롬프트를 열고 다음 명령을 사용하여 Java GitHub 리포지토리용 Azure IoT 샘플을 복제합니다.

    git clone https://github.com/Azure/azure-iot-sdk-java.git --recursive
    
  2. 필요한 모든 패키지를 다운로드하려면 루트 azure-iot-sdk-java 디렉터리로 이동하고 프로젝트를 빌드합니다.

    cd azure-iot-sdk-java
    mvn install -DskipTests=true
    

X.509 인증서 체인 만들기

이 섹션에서는 이 자습서를 사용하여 각 디바이스를 테스트하기 위해 세 개의 인증서로 구성된 X.509 인증서 체인을 생성합니다. 인증서의 계층 구조는 다음과 같습니다.

Diagram that shows relationship of root C A, intermediate C A, and device certificates.

루트 인증서 DPS를 사용하여 루트 인증서를 업로드하고 확인합니다. 이렇게 확인하면 DPS는 루트 인증서를 신뢰하고, 루트 인증서로 서명한 인증서를 확인할 수 있습니다.

중간 인증서: 중간 인증서를 사용하여 디바이스를 제품 라인, 회사 부서 또는 기타 기준에 따라 논리적으로 그룹화하는 것은 매우 흔한 일입니다. 이 자습서에서는 하나의 중간 인증서가 있는 인증서 체인을 사용하지만 프로덕션 시나리오에서는 몇 가지가 있을 수 있습니다. 이 체인의 중간 인증서는 루트 인증서를 통해 서명됩니다. 이 인증서는 DPS에서 만든 등록 그룹에 제공됩니다. 이렇게 구성하면 동일한 중간 인증서로 서명된 디바이스 인증서가 있는 디바이스 그룹 전체를 관리할 수 있습니다.

디바이스 인증서: 디바이스 인증서(리프 인증서라고도 함)는 중간 인증서로 서명되고 프라이빗 키와 함께 디바이스에 저장됩니다. 이상적으로 이러한 중요한 항목은 HSM을 사용하여 안전하게 저장됩니다. 동일한 중간 인증서로 여러 디바이스 인증서에 서명할 수 있습니다. 각 디바이스에서 프로비저닝을 시도할 때 인증서 및 프라이빗 키를 인증서 체인과 함께 제공합니다.

인증서 체인에 대한 자세한 내용은 X.509 인증서 증명을 참조하세요.

X.509 OpenSSL 환경 설정

이 섹션에서는 Openssl 명령에서 사용하는 Openssl 구성 파일, 디렉터리 구조 및 기타 파일을 만듭니다.

  1. Git Bash 명령 프롬프트를 열고 이 자습서의 X.509 인증서 및 키를 생성하려는 폴더로 이동합니다.

  2. 루트 CA 인증서에 대한 openssl_root_ca.cnf라는 OpenSSL 구성 파일을 만듭니다. OpenSSL 구성 파일에는 OpenSSL 명령에서 사용하는 정책 및 정의가 포함되어 있습니다. 다음 텍스트를 복사하여 openssl_root_ca.cnf 파일에 붙여넣습니다.

    # OpenSSL root CA configuration file.
    
    [ ca ]
    default_ca = CA_default
    
    [ CA_default ]
    # Directory and file locations.
    dir               = .
    certs             = $dir/certs
    crl_dir           = $dir/crl
    new_certs_dir     = $dir/newcerts
    database          = $dir/index.txt
    serial            = $dir/serial
    RANDFILE          = $dir/private/.rand
    
    # The root key and root certificate.
    private_key       = $dir/private/azure-iot-test-only.root.ca.key.pem
    certificate       = $dir/certs/azure-iot-test-only.root.ca.cert.pem
    
    # For certificate revocation lists.
    crlnumber         = $dir/crlnumber
    crl               = $dir/crl/azure-iot-test-only.intermediate.crl.pem
    crl_extensions    = crl_ext
    default_crl_days  = 30
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md        = sha256
    
    name_opt          = ca_default
    cert_opt          = ca_default
    default_days      = 375
    preserve          = no
    policy            = policy_loose
    
    [ policy_strict ]
    # The root CA should only sign intermediate certificates that match.
    countryName             = optional
    stateOrProvinceName     = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ policy_loose ]
    # Allow the intermediate CA to sign a more diverse range of certificates.
    countryName             = optional
    stateOrProvinceName     = optional
    localityName            = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ req ]
    default_bits        = 2048
    distinguished_name  = req_distinguished_name
    string_mask         = utf8only
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md          = sha256
    
    # Extension to add when the -x509 option is used.
    x509_extensions     = v3_ca
    
    [ req_distinguished_name ]
    # See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
    countryName                     = Country Name (2 letter code)
    stateOrProvinceName             = State or Province Name
    localityName                    = Locality Name
    0.organizationName              = Organization Name
    organizationalUnitName          = Organizational Unit Name
    commonName                      = Common Name
    emailAddress                    = Email Address
    
    # Optionally, specify some defaults.
    countryName_default             = US
    stateOrProvinceName_default     = WA
    localityName_default            =
    0.organizationName_default      = My Organization
    organizationalUnitName_default  =
    emailAddress_default            =
    
    [ v3_ca ]
    # Extensions for a typical CA.
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ v3_intermediate_ca ]
    # Extensions for a typical intermediate CA.
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ usr_cert ]
    # Extensions for client certificates.
    basicConstraints = CA:FALSE
    nsComment = "OpenSSL Generated Client Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth
    
    [ server_cert ]
    # Extensions for server certificates.
    basicConstraints = CA:FALSE
    nsComment = "OpenSSL Generated Server Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    
    [ crl_ext ]
    # Extension for CRLs.
    authorityKeyIdentifier=keyid:always
    
    [ ocsp ]
    # Extension for OCSP signing certificates.
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, digitalSignature
    extendedKeyUsage = critical, OCSPSigning
    
  3. 중간 및 디바이스 인증서에 사용할 openssl_device_intermediate_ca.cnf라는 OpenSSL 구성 파일을 만듭니다. 다음 텍스트를 복사하여 openssl_device_intermediate_ca.cnf 파일에 붙여넣습니다.

    # OpenSSL root CA configuration file.
    
    [ ca ]
    default_ca = CA_default
    
    [ CA_default ]
    # Directory and file locations.
    dir               = .
    certs             = $dir/certs
    crl_dir           = $dir/crl
    new_certs_dir     = $dir/newcerts
    database          = $dir/index.txt
    serial            = $dir/serial
    RANDFILE          = $dir/private/.rand
    
    # The root key and root certificate.
    private_key       = $dir/private/azure-iot-test-only.intermediate.key.pem
    certificate       = $dir/certs/azure-iot-test-only.intermediate.cert.pem
    
    # For certificate revocation lists.
    crlnumber         = $dir/crlnumber
    crl               = $dir/crl/azure-iot-test-only.intermediate.crl.pem
    crl_extensions    = crl_ext
    default_crl_days  = 30
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md        = sha256
    
    name_opt          = ca_default
    cert_opt          = ca_default
    default_days      = 375
    preserve          = no
    policy            = policy_loose
    
    [ policy_strict ]
    # The root CA should only sign intermediate certificates that match.
    countryName             = optional
    stateOrProvinceName     = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ policy_loose ]
    # Allow the intermediate CA to sign a more diverse range of certificates.
    countryName             = optional
    stateOrProvinceName     = optional
    localityName            = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ req ]
    default_bits        = 2048
    distinguished_name  = req_distinguished_name
    string_mask         = utf8only
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md          = sha256
    
    # Extension to add when the -x509 option is used.
    x509_extensions     = v3_ca
    
    [ req_distinguished_name ]
    # See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
    countryName                     = Country Name (2 letter code)
    stateOrProvinceName             = State or Province Name
    localityName                    = Locality Name
    0.organizationName              = Organization Name
    organizationalUnitName          = Organizational Unit Name
    commonName                      = Common Name
    emailAddress                    = Email Address
    
    # Optionally, specify some defaults.
    countryName_default             = US
    stateOrProvinceName_default     = WA
    localityName_default            =
    0.organizationName_default      = My Organization
    organizationalUnitName_default  =
    emailAddress_default            =
    
    [ v3_ca ]
    # Extensions for a typical CA.
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ v3_intermediate_ca ]
    # Extensions for a typical intermediate CA.
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ usr_cert ]
    # Extensions for client certificates.
    basicConstraints = CA:FALSE
    nsComment = "OpenSSL Generated Client Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth
    
    [ server_cert ]
    # Extensions for server certificates.
    basicConstraints = CA:FALSE
    nsComment = "OpenSSL Generated Server Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    
    [ crl_ext ]
    # Extension for CRLs.
    authorityKeyIdentifier=keyid:always
    
    [ ocsp ]
    # Extension for OCSP signing certificates.
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, digitalSignature
    extendedKeyUsage = critical, OCSPSigning
    
  4. 이 자습서에서 OpenSSL 명령에서 사용하는 디렉터리 구조, 데이터베이스 파일 index.txt 및 일련 번호 파일 직렬 을 만듭니다.

    mkdir certs csr newcerts private
    touch index.txt
    openssl rand -hex 16 > serial
    

루트 CA 인증서 만들기

다음 명령을 실행하여 루트 CA 프라이빗 키 및 루트 CA 인증서를 만듭니다. 이 인증서와 키를 사용하여 중간 인증서에 서명합니다.

  1. Git Bash 터미널에서 루트 CA 프라이빗 키를 만듭니다.

    openssl genrsa -aes256 -passout pass:1234 -out ./private/azure-iot-test-only.root.ca.key.pem 4096
    
  2. 루트 CA 인증서를 만듭니다.

    openssl req -new -x509 -config ./openssl_root_ca.cnf -passin pass:1234 -key ./private/azure-iot-test-only.root.ca.key.pem -subj '//CN=Azure IoT Hub CA Cert Test Only' -days 30 -sha256 -extensions v3_ca -out ./certs/azure-iot-test-only.root.ca.cert.pem
    

    Important

    주체 이름(//CN=Azure IoT Hub CA Cert Test Only)에 제공된 추가 슬래시는 Windows 플랫폼에서 Git을 사용하여 문자열을 이스케이프하는 데만 필요합니다. Linux 플랫폼에서는 제목 이름에 슬래시(/CN=Azure IoT Hub CA Cert Test Only)가 하나만 있습니다.

  3. 루트 CA 인증서 검토:

    openssl x509 -noout -text -in ./certs/azure-iot-test-only.root.ca.cert.pem
    

    발급자주체가 모두 루트 CA인지 확인합니다.

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                1d:93:13:0e:54:07:95:1d:8c:57:4f:12:14:b9:5e:5f:15:c3:a9:d4
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN = Azure IoT Hub CA Cert Test Only
            Validity
                Not Before: Jun 20 22:52:23 2022 GMT
                Not After : Jul 20 22:52:23 2022 GMT
            Subject: CN = Azure IoT Hub CA Cert Test Only
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    RSA Public-Key: (4096 bit)
    

중간 CA 인증서 만들기

다음 명령을 실행하여 중간 CA 프라이빗 키 및 중간 CA 인증서를 만듭니다. 이 인증서와 키를 사용하여 디바이스 인증서에 서명합니다.

  1. Git Bash 터미널에서 중간 CA 프라이빗 키를 만듭니다.

    openssl genrsa -aes256 -passout pass:1234 -out ./private/azure-iot-test-only.intermediate.key.pem 4096
    
  2. 중간 CA 인증서 서명 요청(CSR)을 만듭니다.

    openssl req -new -sha256 -passin pass:1234 -config ./openssl_device_intermediate_ca.cnf -subj '//CN=Azure IoT Hub Intermediate Cert Test Only' -key ./private/azure-iot-test-only.intermediate.key.pem -out ./csr/azure-iot-test-only.intermediate.csr.pem
    

    Important

    주체 이름(//CN=Azure IoT Hub Intermediate Cert Test Only)에 제공된 추가 슬래시는 Windows 플랫폼에서 Git을 사용하여 문자열을 이스케이프하는 데만 필요합니다. Linux 플랫폼에서 주체 이름에 단일 슬래시(/CN=Azure IoT Hub Intermediate Cert Test Only)를 제공합니다.

  3. 루트 CA 인증서를 사용하여 중간 인증서 서명

    openssl ca -batch -config ./openssl_root_ca.cnf -passin pass:1234 -extensions v3_intermediate_ca -days 30 -notext -md sha256 -in ./csr/azure-iot-test-only.intermediate.csr.pem -out ./certs/azure-iot-test-only.intermediate.cert.pem
    
  4. 중간 CA 인증서 검토:

    openssl x509 -noout -text -in ./certs/azure-iot-test-only.intermediate.cert.pem
    

    발급자가 루트 CA이고 주체가 중간 CA인지 확인합니다.

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                d9:55:87:57:41:c8:4c:47:6c:ee:ba:83:5d:ae:db:39
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN = Azure IoT Hub CA Cert Test Only
            Validity
                Not Before: Jun 20 22:54:01 2022 GMT
                Not After : Jul 20 22:54:01 2022 GMT
            Subject: CN = Azure IoT Hub Intermediate Cert Test Only
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    RSA Public-Key: (4096 bit)
    

디바이스 인증서 만들기

이 섹션에서는 두 개의 디바이스 인증서와 전체 체인 인증서를 만듭니다. 전체 체인 인증서에는 디바이스 인증서, 중간 CA 인증서 및 루트 CA 인증서가 포함됩니다. 디바이스는 DPS에 등록할 때 전체 체인 인증서를 제공해야 합니다.

  1. 첫 번째 디바이스 프라이빗 키를 만듭니다.

    openssl genrsa -out ./private/device-01.key.pem 4096
    
  2. 디바이스 인증서 CSR을 만듭니다.

    디바이스 인증서의 주체 CN(일반 이름)은 디바이스가 DPS에 등록하는 데 사용할 등록 ID로 설정해야 합니다. 등록 ID는 영숫자 문자의 대/소문자를 구분하지 않는 문자열과 특수 문자인 '-', '.', '_', ':'입니다. 마지막 문자는 영숫자 또는 대시('-')여야 합니다. 일반 이름은 이 형식을 따라야 합니다. DPS는 최대 128자 길이의 등록 ID를 지원합니다. 그러나 X.509 인증서의 주체 일반 이름의 최대 길이는 64자입니다. 따라서 등록 ID는 X.509 인증서를 사용할 때 64자로 제한됩니다. 그룹 등록의 경우 등록 ID는 IoT Hub의 디바이스 ID로도 사용됩니다.

    주체 일반 이름은 -subj 매개 변수를 사용하여 설정됩니다. 다음 명령에서 일반 이름은 device-01로 설정됩니다.

    openssl req -config ./openssl_device_intermediate_ca.cnf -key ./private/device-01.key.pem -subj '//CN=device-01' -new -sha256 -out ./csr/device-01.csr.pem
    

    Important

    주체 이름(//CN=device-01)에 제공된 추가 슬래시는 Windows 플랫폼에서 Git을 사용하여 문자열을 이스케이프하는 데만 필요합니다. Linux 플랫폼에서 주체 이름에 단일 슬래시(/CN=device-01)를 제공합니다.

  3. 디바이스 인증서에 서명합니다.

    openssl ca -batch -config ./openssl_device_intermediate_ca.cnf -passin pass:1234 -extensions usr_cert -days 30 -notext -md sha256 -in ./csr/device-01.csr.pem -out ./certs/device-01.cert.pem
    
  4. 디바이스 인증서 검토:

    openssl x509 -noout -text -in ./certs/device-01.cert.pem
    

    발급자가 중간 CA이고 주체가 디바이스 등록 ID(device-01)인지 확인합니다.

    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                d9:55:87:57:41:c8:4c:47:6c:ee:ba:83:5d:ae:db:3a
            Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN = Azure IoT Hub Intermediate Cert Test Only
            Validity
                Not Before: Jun 20 22:55:39 2022 GMT
                Not After : Jul 20 22:55:39 2022 GMT
            Subject: CN = device-01
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    RSA Public-Key: (4096 bit)
    
  5. 디바이스는 DPS를 사용하여 인증할 때 전체 인증서 체인을 제공해야 합니다. 다음 명령을 사용하여 인증서 체인을 만듭니다.

    cat ./certs/device-01.cert.pem ./certs/azure-iot-test-only.intermediate.cert.pem ./certs/azure-iot-test-only.root.ca.cert.pem > ./certs/device-01-full-chain.cert.pem
    
  6. 텍스트 편집기에서 ./certs/new-device-01-full-chain.cert.pem 인증서 체인 파일을 열고 검토합니다. 인증서 체인 텍스트에는 세 가지 인증서의 전체 체인이 포함됩니다. 이 자습서의 뒷부분에서 이 인증서 체인을 사용하여 device-01을 프로비전합니다.

    전체 체인 텍스트는 다음과 같은 형식입니다.

    -----BEGIN CERTIFICATE-----
        <Text for the device certificate includes public key>
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
        <Text for the intermediate certificate includes public key>
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
        <Text for the root certificate includes public key>
    -----END CERTIFICATE-----
    
  7. 두 번째 디바이스에 대한 프라이빗 키, X.509 인증서 및 전체 체인 인증서를 만들려면 이 스크립트를 복사하여 Git Bash 명령 프롬프트에 붙여넣습니다. 더 많은 디바이스에 대한 인증서를 만들려면 스크립트의 시작 부분에 선언된 registration_id 변수를 수정할 수 있습니다.

    registration_id=device-02
    echo $registration_id
    openssl genrsa -out ./private/${registration_id}.key.pem 4096
    openssl req -config ./openssl_device_intermediate_ca.cnf -key ./private/${registration_id}.key.pem -subj "//CN=$registration_id" -new -sha256 -out ./csr/${registration_id}.csr.pem
    openssl ca -batch -config ./openssl_device_intermediate_ca.cnf -passin pass:1234 -extensions usr_cert -days 30 -notext -md sha256 -in ./csr/${registration_id}.csr.pem -out ./certs/${registration_id}.cert.pem
    cat ./certs/${registration_id}.cert.pem ./certs/azure-iot-test-only.intermediate.cert.pem ./certs/azure-iot-test-only.root.ca.cert.pem > ./certs/${registration_id}-full-chain.cert.pem
    

    Important

    주체 이름(//CN=$registration_id)에 제공된 추가 슬래시는 Windows 플랫폼에서 Git을 사용하여 문자열을 이스케이프하는 데만 필요합니다. Linux 플랫폼에서 주체 이름에 단일 슬래시(/CN=$registration_id)를 제공합니다.

    참고 항목

    이 스크립트는 등록 ID를 프라이빗 키 및 인증서 파일의 기본 파일 이름으로 사용합니다. 등록 ID에 유효한 파일 이름 문자가 아닌 문자가 포함된 경우 그에 따라 스크립트를 수정해야 합니다.

    Warning

    인증서의 텍스트에는 공개 키 정보만 포함됩니다.

    그러나 디바이스는 디바이스 인증서의 프라이빗 키에 대한 액세스 권한도 필요합니다. 프로비저닝을 시도할 때 디바이스에서 런타임에 해당 키를 사용하여 확인을 수행해야 하기 때문에 이 액세스 권한이 필요합니다. 이 키는 매우 중요하기 때문에 실제 HSM에서는 프라이빗 키를 안전하게 보관할 수 있도록 하드웨어 기반 스토리지를 사용하는 것이 좋습니다.

이 자습서의 나머지 부분에는 다음 파일이 사용됩니다.

인증서 파일 설명
루트 CA 인증서 certs/azure-iot-test-only.root.ca.cert.pem DPS에 업로드되고 확인됩니다.
중간 CA 인증서 certs/azure-iot-test-only.intermediate.cert.pem DPS에서 등록 그룹을 만드는 데 사용됩니다.
device-01 프라이빗 키 private/device-01.key.pem 인증하는 동안 디바이스에서 DPS를 사용하여 디바이스 인증서의 소유권을 확인하는 데 사용됩니다.
device-01 전체 체인 인증서 certs/device-01-full-chain.cert.pem DPS를 인증하고 등록하기 위해 디바이스에서 제공합니다.
device-02 프라이빗 키 private/device-02.key.pem 인증하는 동안 디바이스에서 DPS를 사용하여 디바이스 인증서의 소유권을 확인하는 데 사용됩니다.
device-02 전체 체인 인증서 certs/device-02-full-chain.cert.pem DPS를 인증하고 등록하기 위해 디바이스에서 제공합니다.

루트 인증서의 소유권 확인

DPS가 인증 중에 디바이스의 인증서 체인의 유효성을 검사하려면 루트 CA 인증서의 소유권을 업로드하고 확인해야 합니다. DPS 인스턴스에 루트 CA 인증서를 추가하려면 다음 단계를 수행합니다.

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

  2. 왼쪽 메뉴에서 인증서를 연 다음 추가를 선택하여 새 인증서를 추가합니다.

  3. 인증서의 표시 이름을 입력합니다. 루트 CA 인증서 파일 certs/azure-iot-test-only.root.ca.cert.pem의 위치로 이동합니다. 업로드를 선택합니다.

  4. 업로드확인할 인증서 상태 설정하는 상자를 선택합니다.

    Screenshot that shows adding the root CA certificate and the set certificate status to verified on upload box selected.

  5. 저장을 선택합니다.

  6. 인증서가 인증서 탭에 확인됨 상태로 표시됩니다.

    Screenshot that shows the verified root C A certificate in the list of certificates.

Windows 기반 디바이스의 인증서 저장소 업데이트

Windows 이외의 디바이스는 코드에서 인증서 체인을 인증서 저장소로 전달할 수 있습니다.

Windows 기반 디바이스는 서명 인증서(루트 및 중간)를 Windows 인증서 저장소에 추가해야 합니다. 그렇지 않으면 TLS(전송 계층 보안)를 사용하는 보안 채널을 통해 서명 인증서가 DPS로 전송되지 않습니다.

C SDK에서 보안 채널(Schannel) 대신 OpenSSL을 사용할 수도 있습니다. OpenSSL을 사용하는 방법에 대한 자세한 내용은 SDK에서 OpenSSL 사용을 참조하세요.

Windows 기반 디바이스에서 인증서 저장소에 서명 인증서를 추가하려면 다음을 수행합니다.

  1. Git Bash 터미널에서 서명 인증서를 .pfx 다음과 같이 변환합니다.

    루트 CA 인증서:

    openssl pkcs12 -inkey ./private/azure-iot-test-only.root.ca.key.pem -in ./certs/azure-iot-test-only.root.ca.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/root.pfx
    

    중간 CA 인증서:

    openssl pkcs12 -inkey ./private/azure-iot-test-only.intermediate.key.pem -in ./certs/azure-iot-test-only.intermediate.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/intermediate.pfx
    
  2. Windows 시작 단추를 마우스 오른쪽 단추로 클릭한 다음 실행을 선택합니다. certmgr.msc를 입력하고 확인을 선택하여 인증서 관리자를 시작합니다.

  3. 인증서 관리자의 인증서 - 현재 사용자에서 신뢰할 수 있는 루트 인증 기관을 선택합니다. 그런 다음 메뉴에서 모든 작업>가져오기 작업을>선택합니다.

  4. 인증서 가져오기 마법사 단계에 따라 가져옵니다 root.pfx.

    • 개인 정보 교환(.pfx)으로 검색합니다.
    • 1234를 암호로 사용합니다.
    • 인증서를 신뢰할 수 있는 루트 인증 기관 인증서 저장소에 배치합니다.
  5. 이러한 인증서 관리자 단계를 반복하여 가져옵니다 intermediate.pfx.

    • 인증서를 중간 인증 기관 인증서 저장소에 배치합니다.

이제 Windows 기반 디바이스에서 서명 인증서를 신뢰하며 전체 체인을 DPS로 전송할 수 있습니다.

등록 그룹 만들기

  1. Azure Portal에 로그인하고, Device Provisioning Service 인스턴스로 이동합니다.

  2. 탐색 메뉴의 설정 섹션에서 등록 관리를 선택합니다.

  3. 페이지 위쪽에서 등록 그룹 추가를 선택합니다.

  4. 등록 그룹 추가 페이지의 등록 + 프로비저닝 탭에서 다음 정보를 제공하여 등록 그룹 세부 정보를 구성합니다.

    필드 설명
    증명 이 등록 그룹에만 사용할 중간 인증서를 업로드하려면 X.509 중간 인증서증명 메커니즘으로 선택하거나, 중간 인증서를 이미 업로드한 경우 이 Device Provisioning Service에 업로드된 X.509 인증서를 선택합니다.
    X.509 인증서 설정 선택한 증명 방법에 따라 이 등록 그룹에 대한 기본 및 보조 중간 인증서를 업로드하거나 선택합니다.
    그룹 이름 디바이스 그룹의 이름을 제공합니다. 등록 그룹 이름은 영숫자 문자의 대/소문자를 구분하지 않는 문자열(최대 128자 길이)과 특수 문자인 '-', '.', '_', ':'입니다. 마지막 문자는 영숫자 또는 대시('-')여야 합니다.
    프로비전 상태 디바이스를 프로비전하는 데 이 등록 그룹을 사용할 수 있도록 하려면 이 등록 사용 확인란을 선택합니다. 그룹을 사용하지 않도록 설정하려면 이 확인란의 선택을 취소합니다. 이 설정은 나중에 변경할 수 있습니다.
    재프로비전 정책 DPS가 다시 프로비전을 요청하는 디바이스를 처리하는 방법을 반영하는 재프로비전 정책을 선택합니다. 자세한 내용은 정책 다시 프로비전을 참조하세요

    Screenshot that shows adding an enrollment group for X.509 certificate attestation.

  5. 다음: IoT 허브를 선택합니다.

  6. 등록 그룹 추가 페이지의 IoT 허브 탭에서 다음 정보를 제공하여 등록 그룹이 디바이스를 프로비전할 수 있는 IoT 허브를 결정합니다.

    필드 설명
    대상 IoT 허브 연결된 IoT 허브 중 하나 이상을 선택하거나 IoT 허브에 새 링크를 추가합니다. DPS 인스턴스에 IoT 허브를 연결하는 방법에 대해 자세히 알아보려면 IoT 허브 연결 및 관리 방법을 참조하세요.
    할당 정책 둘 이상의 연결된 IoT 허브를 선택한 경우 디바이스를 다른 허브에 할당할 방법을 선택합니다. 할당 정책에 대한 자세한 내용은 할당 정책 사용 방법을 참조하세요.

    연결된 IoT 허브를 하나만 선택한 경우 동일 가중 배포 정책을 사용하는 것이 좋습니다.

    Screenshot that shows connecting IoT hubs to the new enrollment group.

  7. 다음: 디바이스 설정을 선택합니다

  8. 등록 그룹 추가 페이지의 디바이스 설정 탭에서 다음 정보를 제공하여 새로 프로비전된 디바이스를 구성하는 방법을 정의합니다.

    필드 설명
    IoT Edge 이 그룹을 통해 프로비전된 모든 디바이스가 Azure IoT Edge를 실행하는 경우 프로비전된 디바이스에서 IoT Edge 사용을 선택합니다. 이 그룹이 비 IoT Edge 지원 디바이스에만 해당되는 경우 이 확인란의 선택을 취소합니다. 그룹의 모든 디바이스는 IoT Edge를 사용하도록 설정되거나 아무것도 사용할 수 없습니다.
    디바이스 태그 프로비전된 디바이스의 디바이스 쌍에 적용하려는 태그를 제공하려면 이 텍스트 상자를 사용합니다.
    원하는 속성 프로비전된 디바이스의 디바이스 쌍에 적용하려는 원하는 속성을 제공하려면 이 텍스트 상자를 사용합니다.

    자세한 내용은 IoT Hub의 디바이스 쌍 이해 및 사용을 참조하세요.

  9. 완료되면 다음: 리뷰 + 만들기를 클릭합니다.

  10. 검토 + 만들기 탭에서 모든 값을 확인한 다음 만들기를 선택합니다.

디바이스 프로비저닝 코드 준비 및 실행

이 섹션에서는 샘플 코드를 Device Provisioning Service 인스턴스 정보로 업데이트합니다. 디바이스가 인증되면 이 섹션에 구성한 Device Provisioning Service 인스턴스에 연결된 IoT 허브에 디바이스가 할당됩니다.

이 섹션에서는 Git Bash 프롬프트와 Visual Studio IDE를 사용합니다.

프로비저닝 디바이스 코드 구성

이 섹션에서는 샘플 코드를 Device Provisioning Service 인스턴스 정보로 업데이트합니다.

  1. Azure Portal에서 Device Provisioning Service 인스턴스에 대한 개요 탭을 선택하고 ID 범위 값을 기록해 둡니다.

    Screenshot that shows the ID scope on the DPS overview pane.

  2. Visual Studio를 시작하고, azure-iot-sdk-c git 리포지토리의 루트에 만든 cmake 디렉터리에 생성된 새 솔루션 파일을 엽니다. 솔루션 파일의 이름은 azure_iot_sdks.sln입니다.

  3. Visual Studio의 솔루션 탐색기에서 Provision_Samples > prov_dev_client_sample > 원본 파일로 이동하여 prov_dev_client_sample.c를 엽니다.

  4. id_scope 상수를 찾고, 값을 앞에서 복사한 ID 범위 값으로 바꿉니다. 예시:

    static const char* id_scope = "0ne00000A0A";
    
  5. 동일한 파일에서 main() 함수에 대한 정의를 찾습니다. hsm_type 변수가 SECURE_DEVICE_TYPE_X509로 설정되어 있고 다른 모든 hsm_type 줄이 주석 처리되는지 확인합니다. 예를 들면 다음과 같습니다.

    SECURE_DEVICE_TYPE hsm_type;
    //hsm_type = SECURE_DEVICE_TYPE_TPM;
    hsm_type = SECURE_DEVICE_TYPE_X509;
    //hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;
    
  6. 변경 내용을 저장합니다.

  7. prov_dev_client_sample 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 시작 프로젝트로 설정을 선택합니다.

사용자 지정 HSM 스텁 코드 구성

실제 보안 하드웨어 기반 스토리지와 이루어지는 구체적인 상호 작용은 디바이스 하드웨어에 따라 달라집니다. 이 자습서의 시뮬레이션된 디바이스에서 사용되는 인증서 체인은 사용자 지정 HSM 스텁 코드에서 하드 코딩됩니다. 실제 시나리오에서 인증서 체인은 중요한 정보를 보다 안전하게 보호하기 위해 실제 HSM 하드웨어에 저장됩니다. 그런 다음, 이 샘플에 사용된 스텁 메서드와 비슷한 메서드를 구현하여 해당 하드웨어 기반 스토리지에서 비밀을 읽습니다.

HSM 하드웨어가 필요하지는 않지만 인증서의 프라이빗 키와 같은 중요한 정보를 보호하는 것이 좋습니다. 샘플에서 실제 HSM을 호출하는 경우 프라이빗 키는 소스 코드에 표시되지 않습니다. 키가 소스 코드에 있으면 해당 키가 코드를 볼 수 있는 모든 사용자에게 공개됩니다. 이 자습서에서는 학습을 지원하기 위해서만 이 작업을 수행합니다.

ID가 device-01인 디바이스의 ID를 시뮬레이션하도록 사용자 지정 HSM 스텁 코드를 업데이트하려면 다음을 수행합니다.

  1. Visual Studio의 솔루션 탐색기에서 Provisioning_Samples > custom_hsm_example > 원본 파일로 이동하여 custom_hsm_example.c를 엽니다.

  2. 디바이스 인증서를 생성할 때 사용한 일반적인 이름을 사용하여 COMMON_NAME 문자열 상수의 문자열 값을 업데이트합니다.

    static const char* const COMMON_NAME = "device-01";
    
  3. Git Bash 터미널에서 다음 명령을 실행하여 디바이스 인증서에 대한 문자열 상수를 생성합니다.

    sed -e 's/^/"/;$ !s/$/""\\n"/;$ s/$/"/' ./certs/device-01-full-chain.cert.pem
    

    이 명령의 출력을 복사합니다.

  4. 인증서를 생성한 후 ./certs/device-01-full-chain.cert.pem에 저장한 인증서 체인을 사용하여 CERTIFICATE 상수 문자열의 문자열 값을 업데이트합니다. 상수 값에 대해 이전 단계의 출력 인증서 텍스트를 사용합니다.

    인증서 텍스트 구문은 Visual Studio에서 수행된 추가 공백이나 구문 분석 없이 다음 패턴과 일치해야 합니다.

    // <Device/leaf cert>
    // <intermediates>
    // <root>
    static const char* const CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"
    "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n"
        ...
    "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n"
    "-----END CERTIFICATE-----\n"
    "-----BEGIN CERTIFICATE-----\n"
    "MIIFPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDDB9BenVy\n"
        ...
    "MTEyMjIxMzAzM1owNDEyMDAGA1UEAwwpQXp1cmUgSW9UIEh1YiBJbnRlcm1lZGlh\n"
    "-----END CERTIFICATE-----\n"
    "-----BEGIN CERTIFICATE-----\n"
    "MIIFOjCCAyKgAwIBAgIJAPzMa6s7mj7+MA0GCSqGSIb3DQEBCwUAMCoxKDAmBgNV\n"
        ...
    "MDMwWhcNMjAxMTIyMjEzMDMwWjAqMSgwJgYDVQQDDB9BenVyZSBJb1QgSHViIENB\n"
    "-----END CERTIFICATE-----";        
    
  5. Git Bash에서 다음 명령을 실행하여 디바이스 프라이빗 키에 대한 문자열 상수 생성:

    sed -e 's/^/"/;$ !s/$/""\\n"/;$ s/$/"/' ./private/device-01.key.pem
    

    이 명령의 출력을 복사합니다.

  6. 디바이스 인증서의 프라이빗 키를 사용하여 PRIVATE_KEY 상수의 문자열 값을 업데이트합니다. 상수 값에 대해 이전 단계의 출력 프라이빗 키 텍스트를 사용합니다.

    프라이빗 키 텍스트의 구문은 Visual Studio에서 수행된 추가 공백이나 구문 분석 없이 다음 패턴과 일치해야 합니다.

    static const char* const PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\n"
    "MIIJJwIBAAKCAgEAtjvKQjIhp0EE1PoADL1rfF/W6v4vlAzOSifKSQsaPeebqg8U\n"
        ...
    "X7fi9OZ26QpnkS5QjjPTYI/wwn0J9YAwNfKSlNeXTJDfJ+KpjXBcvaLxeBQbQhij\n"
    "-----END RSA PRIVATE KEY-----";
    
  7. 변경 내용을 저장합니다.

  8. custom_hsm_example 프로젝트를 마우스 오른쪽 단추로 클릭하고 빌드를 선택합니다.

    Important

    다음 섹션에서 나머지 솔루션을 빌드하기 전에 custom_hsm_example 프로젝트를 빌드해야 합니다.

샘플 실행

  1. Visual Studio 메뉴에서 디버그>디버깅하지 않고 시작을 선택하여 솔루션을 실행합니다. 프로젝트를 다시 빌드하라는 메시지가 표시되면 를 선택하여 프로젝트를 다시 빌드한 후 실행합니다.

    다음 출력은 성공적으로 부팅되고 프로비저닝 서비스에 연결하는 device-01 시뮬레이션된 디바이스에 대한 예제입니다. 이 디바이스는 IoT 허브에 할당되고 등록되었습니다.

    Provisioning API Version: 1.8.0
    
    Registering Device
    
    Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED
    Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING
    
    Registration Information received from service: contoso-hub-2.azure-devices.net, deviceId: device-01
    Press enter key to exit:
    
  2. 두 번째 디바이스(device-02)에 대한 사용자 지정 HSM 스텁 코드 구성의 단계를 반복하고 샘플을 다시 실행합니다. 해당 디바이스에 대해 다음 값을 사용합니다.

    설명
    일반 이름 "device-02"
    전체 인증서 체인 ./certs/device-02-full-chain.cert.pem을 사용하여 텍스트 생성
    프라이빗 키 ./private/device-02.key.pem을 사용하여 텍스트 생성

    다음 출력은 성공적으로 부팅되고 프로비저닝 서비스에 연결하는 device-02 시뮬레이션된 디바이스에 대한 예제입니다. 이 디바이스는 IoT 허브에 할당되고 등록되었습니다.

    Provisioning API Version: 1.8.0
    
    Registering Device
    
    Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED
    Provisioning Status: PROV_DEVICE_REG_STATUS_ASSIGNING
    
    Registration Information received from service: contoso-hub-2.azure-devices.net, deviceId: device-02
    Press enter key to exit:
    

C# 샘플 코드는 암호로 보호된 PKCS#12 형식 파일(.pfx)에 저장된 X.509 인증서를 사용하도록 설정되어 있습니다. 이전에 만든 전체 체인 인증서는 PEM 형식입니다. 전체 체인 인증서를 PKCS#12 형식으로 변환하려면 이전에 OpenSSL 명령을 실행한 디렉터리의 Git Bash 프롬프트에 다음 명령을 입력합니다.

  • device-01

    openssl pkcs12 -inkey ./private/device-01.key.pem -in ./certs/device-01-full-chain.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/device-01-full-chain.cert.pfx
    
  • device-02

    openssl pkcs12 -inkey ./private/device-02.key.pem -in ./certs/device-02-full-chain.cert.pem -export -passin pass:1234 -passout pass:1234 -out ./certs/device-02-full-chain.cert.pfx
    

이 섹션의 나머지 부분에서는 Windows 명령 프롬프트를 사용합니다.

  1. Azure Portal에서 Device Provisioning Service의 개요 탭을 선택합니다.

  2. ID 범위 값을 복사합니다.

    Screenshot of the ID scope on Azure portal.

  3. Windows 명령 프롬프트에서 X509Sample 디렉터리로 변경합니다. 이 디렉터리는 이전 단계에서 복제한 SDK 리포지토리에 있습니다. .\azure-iot-sdk-csharp\provisioning\device\samples\getting started\X509Sample.

  4. 다음 명령을 입력하여 X.509 디바이스 프로비저닝 샘플을 빌드하고 실행합니다. Azure Portal에서 복사한 ID 범위로 바꿉 <id-scope> 니다. <your-certificate-folder>를 OpenSSL 명령을 실행한 폴더의 경로로 바꿉니다.

    dotnet run -- -s <id-scope> -c <your-certificate-folder>\certs\device-01-full-chain.cert.pfx -p 1234
    

    디바이스가 DPS에 연결되고 IoT 허브에 할당됩니다. 그런 다음 디바이스는 원격 분석 메시지를 IoT Hub로 보냅니다. 다음 예제와 비슷한 내용이 출력됩니다.

    Loading the certificate...
    Found certificate: 3E5AA3C234B2032251F0135E810D75D38D2AA477 CN=Azure IoT Hub CA Cert Test Only; PrivateKey: False
    Found certificate: 81FE182C08D18941CDEEB33F53F8553BA2081E60 CN=Azure IoT Hub Intermediate Cert Test Only; PrivateKey: False
    Found certificate: 5BA1DB226D50EBB7A6A6071CED4143892855AE43 CN=device-01; PrivateKey: True
    Using certificate 5BA1DB226D50EBB7A6A6071CED4143892855AE43 CN=device-01
    Initializing the device provisioning client...
    Initialized for registration Id device-01.
    Registering with the device provisioning service...
    Registration status: Assigned.
    Device device-01 registered to contoso-hub-2.azure-devices.net.
    Creating X509 authentication for IoT Hub...
    Testing the provisioned device with IoT Hub...
    Sending a telemetry message...
    Finished.
    

    참고 항목

    명령줄에서 인증서 및 암호를 지정하지 않으면 인증서 파일은 기본적으로 ./certificate.pfx 로 설정되며 암호를 입력하라는 메시지가 표시됩니다.

    TransportType(-t) 및 GlobalDeviceEndpoint(-g)를 변경하기 위해 추가 매개 변수를 전달할 수 있습니다. 매개 변수 목록 전체를 보려면 dotnet run -- --help를 입력합니다.

  5. 두 번째 디바이스를 등록하려면 전체 체인 인증서를 사용하여 샘플을 다시 실행합니다.

    dotnet run -- -s <id-scope> -c <your-certificate-folder>\certs\device-02-full-chain.cert.pfx -p 1234
    

다음 단계에서는 Windows 명령 프롬프트를 사용합니다.

  1. Azure Portal에서 Device Provisioning Service의 개요 탭을 선택합니다.

  2. ID 범위 값을 복사합니다.

    Screenshot of the ID scope in the Azure portal.

  3. Windows 명령 프롬프트에서 샘플 디렉터리로 이동하고 샘플에 필요한 패키지를 설치합니다. 표시된 경로는 SDK를 복제한 위치에 상대적입니다.

    cd .\azure-iot-sdk-node\provisioning\device\samples
    npm install
    
  4. provisioning\device\samples 폴더에서 register_x509.js를 열고, 코드를 검토합니다.

    샘플은 기본적으로 전송 프로토콜로 MQTT로 설정됩니다. 다른 프로토콜을 사용하려는 경우 다음 줄을 주석으로 처리하고 적절한 프로토콜에 대한 줄의 주석 처리를 제거합니다.

    var ProvisioningTransport = require('azure-iot-provisioning-device-mqtt').Mqtt;
    

    이 샘플은 5개의 환경 변수를 사용하여 DPS를 사용하여 IoT 디바이스를 인증하고 프로비전합니다. 이러한 환경 변수는 다음과 같습니다.

    변수 이름 설명
    PROVISIONING_HOST DPS 인스턴스에 연결하는 데 사용할 엔드포인트입니다. 이 자습서에서는 전역 엔드포인트 global.azure-devices-provisioning.net을 사용합니다.
    PROVISIONING_IDSCOPE DPS 인스턴스의 ID 범위입니다.
    PROVISIONING_REGISTRATION_ID 디바이스의 등록 ID입니다. 디바이스 인증서의 주체 일반 이름과 일치해야 합니다.
    CERTIFICATE_FILE 디바이스 전체 체인 인증서 파일의 경로입니다.
    KEY_FILE 디바이스 인증서 프라이빗 키 파일의 경로입니다.

    ProvisioningDeviceClient.register() 메서드가 디바이스를 등록하려고 시도합니다.

  5. 전역 디바이스 엔드포인트 및 ID 범위에 대한 환경 변수를 추가합니다. Azure Portal에서 복사한 값으로 바꿉 <id-scope> 니다.

    set PROVISIONING_HOST=global.azure-devices-provisioning.net
    set PROVISIONING_IDSCOPE=<id-scope>
    
  6. 디바이스 등록 ID에 대한 환경 변수를 설정합니다. IoT 디바이스의 등록 ID는 해당 디바이스 인증서의 주체 일반 이름과 일치해야 합니다. 이 자습서에서 device-01은 디바이스의 주체 이름과 등록 ID입니다.

    set PROVISIONING_REGISTRATION_ID=device-01
    
  7. 이전에 생성한 디바이스 전체 체인 인증서 및 디바이스 프라이빗 키 파일에 대한 환경 변수를 설정합니다. <your-certificate-folder>를 OpenSSL 명령을 실행한 폴더의 경로로 바꿉니다.

    set CERTIFICATE_FILE=<your-certificate-folder>\certs\device-01-full-chain.cert.pem
    set KEY_FILE=<your-certificate-folder>\private\device-01.key.pem
    
  8. 샘플을 실행하고 디바이스가 성공적으로 프로비전되었는지 확인합니다.

    node register_x509.js
    

    다음 예제와 비슷한 내용이 출력됩니다.

    registration succeeded
    assigned hub=contoso-hub-2.azure-devices.net
    deviceId=device-01
    Client connected
    send status: MessageEnqueued
    
  9. 다음 표에 따라 두 번째 디바이스(device-02)의 환경 변수를 업데이트하고 샘플을 다시 실행합니다.

    환경 변수
    PROVISIONING_REGISTRATION_ID device-02
    CERTIFICATE_FILE <your-certificate-folder>\certs\device-02-full-chain.cert.pem
    KEY_FILE <your-certificate-folder>\private\device-02.key.pem

다음 단계에서는 Windows 명령 프롬프트를 사용합니다.

  1. Azure Portal에서 Device Provisioning Service의 개요 탭을 선택합니다.

  2. ID 범위 값을 복사합니다.

    Screenshot of the ID scope in the Azure portal.

  3. Windows 명령 프롬프트에서 provision_x509.py 샘플 디렉터리로 이동합니다. 표시된 경로는 SDK를 복제한 위치에 상대적입니다.

    cd .\azure-iot-sdk-python\samples\async-hub-scenarios
    

    이 샘플에서는 6개의 환경 변수를 사용하여 DPS를 사용하여 IoT 디바이스를 인증하고 프로비저닝합니다. 이러한 환경 변수는 다음과 같습니다.

    변수 이름 설명
    PROVISIONING_HOST DPS 인스턴스에 연결하는 데 사용할 엔드포인트입니다. 이 자습서에서는 전역 엔드포인트 global.azure-devices-provisioning.net을 사용합니다.
    PROVISIONING_IDSCOPE DPS 인스턴스의 ID 범위입니다.
    DPS_X509_REGISTRATION_ID 디바이스의 등록 ID입니다. 디바이스 인증서의 주체 일반 이름과 일치해야 합니다.
    X509_CERT_FILE 디바이스 전체 체인 인증서 파일의 경로입니다.
    X509_KEY_FILE 디바이스 인증서 프라이빗 키 파일의 경로입니다.
    PASS_PHRASE 프라이빗 키 파일(사용한 경우)을 암호화하는 데 사용된 암호입니다. 이 자습서에는 필요하지 않습니다.
  4. 전역 디바이스 엔드포인트 및 ID 범위에 대한 환경 변수를 추가합니다. ID 범위 변수의 경우 Azure Portal에서 복사한 값을 사용합니다.

    set PROVISIONING_HOST=global.azure-devices-provisioning.net
    set PROVISIONING_IDSCOPE=<ID scope for your DPS resource>
    
  5. 디바이스 등록 ID에 대한 환경 변수를 설정합니다. IoT 디바이스의 등록 ID는 해당 디바이스 인증서의 주체 일반 이름과 일치해야 합니다. 이 자습서에서 device-01은 디바이스의 주체 이름과 등록 ID입니다.

    set DPS_X509_REGISTRATION_ID=device-01
    
  6. 이전에 생성한 디바이스 전체 체인 인증서 및 디바이스 프라이빗 키 파일에 대한 환경 변수를 설정합니다. <your-certificate-folder>를 OpenSSL 명령을 실행한 폴더의 경로로 바꿉니다.

    set X509_CERT_FILE=<your-certificate-folder>\certs\device-01-full-chain.cert.pem
    set X509_KEY_FILE=<your-certificate-folder>\private\device-01.key.pem
    
  7. provision_x509.py에 대한 코드를 검토합니다. Python 버전 3.7 이상을 사용하지 않는 경우 여기에 설명된 대로 코드를 변경하여 asyncio.run(main())을 대체합니다.

  8. 예제를 실행합니다. 샘플은 디바이스를 IoT 허브에 프로비전하는 DPS에 연결합니다. 디바이스가 프로비전된 후 샘플은 일부 테스트 메시지를 IoT Hub로 보냅니다.

    python provision_x509.py
    

    다음 예제와 비슷한 내용이 출력됩니다.

    The complete registration result is
    device-01
    contoso-hub-2.azure-devices.net
    initialAssignment
    null
    Will send telemetry from the provisioned device
    sending message #1
    sending message #2
    sending message #3
    sending message #4
    sending message #5
    sending message #6
    sending message #7
    sending message #8
    sending message #9
    sending message #10
    done sending message #1
    done sending message #2
    done sending message #3
    done sending message #4
    done sending message #5
    done sending message #6
    done sending message #7
    done sending message #8
    done sending message #9
    done sending message #10
    
  9. 다음 표에 따라 두 번째 디바이스(device-02)의 환경 변수를 업데이트하고 샘플을 다시 실행합니다.

    환경 변수
    DPS_X509_REGISTRATION_ID device-02
    X509_CERT_FILE <your-certificate-folder>\certs\device-02-full-chain.cert.pem
    X509_KEY_FILE <your-certificate-folder>\private\device-02.key.pem

다음 단계에서는 Windows 명령 프롬프트와 Git Bash 프롬프트를 모두 사용합니다.

  1. Azure Portal에서 Device Provisioning Service의 개요 탭을 선택합니다.

  2. ID 범위 값을 복사합니다.

    Screenshot of the ID scope in the Azure portal.

  3. Windows 명령 프롬프트에서 샘플 프로젝트 폴더로 이동합니다. 표시된 경로는 SDK를 복제한 위치에 상대적입니다

    cd .\azure-iot-sdk-java\provisioning\provisioning-device-client-samples\provisioning-X509-sample
    
  4. 샘플 코드에 프로비전 서비스 및 X.509 ID 정보를 입력합니다. 디바이스를 등록하기 전에, 프로비저닝하는 동안 시뮬레이션된 디바이스의 증명을 위해 사용됩니다.

    1. 원하는 편집기에서 .\src\main\java\samples\com\microsoft\azure\sdk\iot\ProvisioningX509Sample.java 파일을 엽니다.

    2. 다음 값을 업데이트합니다. idScope의 경우 이전에 복사한 ID 범위를 사용합니다. 글로벌 엔드포인트의 경우 전역 디바이스 엔드포인트를 사용합니다. 이 엔드포인트는 모든 DPS 인스턴스(global.azure-devices-provisioning.net)에 대해 동일합니다.

      private static final String idScope = "[Your ID scope here]";
      private static final String globalEndpoint = "[Your Provisioning Service Global Endpoint here]";
      
    3. 샘플은 전송 프로토콜로 HTTPS를 사용하도록 기본 설정됩니다. 프로토콜을 변경하려는 경우 다음 줄을 주석으로 처리하고 사용할 프로토콜에 대한 줄의 주석 처리를 제거합니다.

      private static final ProvisioningDeviceClientTransportProtocol PROVISIONING_DEVICE_CLIENT_TRANSPORT_PROTOCOL = ProvisioningDeviceClientTransportProtocol.HTTPS;
      
    4. leafPublicPem 상수 문자열의 값을 디바이스 인증서 값 device-01.cert.pem으로 업데이트합니다.

      인증서 텍스트의 구문은 공백이나 문자가 없는 다음 패턴과 일치해야 합니다.

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

      이 문자열 값을 수동으로 업데이트하면 오류가 발생하기 쉽습니다. 올바른 구문을 생성하려면 다음 명령을 복사하여 Git Bash 프롬프트에 붙여넣고 ENTER를 누릅니다. 이 명령은 leafPublicPem 문자열 상수 값에 대한 구문을 생성하고 출력에 씁니다.

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

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

    5. 디바이스 인증서 unencrypted-device-key.pem의 암호화되지 않은 프라이빗 키로 leafPrivateKey 상수의 문자열 값을 업데이트합니다.

      프라이빗 키 텍스트의 구문은 공백이나 문자가 없는 다음 패턴과 일치해야 합니다.

      private static final String leafPrivateKey = "-----BEGIN PRIVATE KEY-----\n" +
      "MIIJJwIBAAKCAgEAtjvKQjIhp0EE1PoADL1rfF/W6v4vlAzOSifKSQsaPeebqg8U\n" +
          ...
      "X7fi9OZ26QpnkS5QjjPTYI/wwn0J9YAwNfKSlNeXTJDfJ+KpjXBcvaLxeBQbQhij\n" +
      "-----END PRIVATE KEY-----";
      

      올바른 구문을 생성하려면 다음 명령을 복사하여 Git Bash 프롬프트에 붙여넣고 ENTER를 누릅니다. 이 명령은 leafPrivateKey 문자열 상수 값에 대한 구문을 생성하고 출력에 씁니다.

      sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./private/device-01.key.pem
      

      상수 값에 대한 출력 프라이빗 키 텍스트를 복사하여 붙여넣습니다.

    6. 루트 CA 인증서 값이 azure-iot-test-only.root.ca.cert.pemrootPublicPem 상수 문자열을 추가합니다. leafPrivateKey 상수 바로 다음에 추가할 수 있습니다.

      인증서 텍스트의 구문은 공백이나 문자가 없는 다음 패턴과 일치해야 합니다.

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

      올바른 구문을 생성하려면 다음 명령을 복사하여 Git Bash 프롬프트에 붙여넣고 ENTER를 누릅니다. 이 명령은 rootPublicPem 문자열 상수 값에 대한 구문을 생성하고 출력에 씁니다.

      sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./certs/azure-iot-test-only.root.ca.cert.pem
      

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

    7. 중간 CA 인증서 값이 azure-iot-test-only.intermediate.ca.cert.pemintermediatePublicPem 상수 문자열을 추가합니다. 이전 상수 바로 다음에 추가할 수 있습니다.

      인증서 텍스트의 구문은 공백이나 문자가 없는 다음 패턴과 일치해야 합니다.

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

      올바른 구문을 생성하려면 다음 명령을 복사하여 Git Bash 프롬프트에 붙여넣고 ENTER를 누릅니다. 이 명령은 intermediatePublicPem 문자열 상수 값에 대한 구문을 생성하고 출력에 씁니다.

      sed 's/^/"/;$ !s/$/\\n" +/;$ s/$/"/' ./certs/azure-iot-test-only.intermediate.cert.pem
      

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

    8. main 메서드에 다음 줄을 추가합니다.

      // For group enrollment uncomment this line
      //signerCertificatePemList.add("<Your Signer/intermediate Certificate Here>");
      

      이러한 두 줄을 바로 아래에 추가하여 서명 체인에 중간 및 루트 CA 인증서를 추가합니다. 서명 체인에는 DPS로 확인한 인증서를 포함하여 전체 인증서 체인이 포함되어야 합니다.

      signerCertificatePemList.add(intermediatePublicPem);
      signerCertificatePemList.add(rootPublicPem);
      

      참고 항목

      서명 인증서가 추가되는 순서가 중요합니다. 변경되면 샘플이 실패합니다.

    9. 변경 내용을 저장합니다.

  5. 샘플을 빌드한 다음 target 폴더로 이동합니다.

    mvn clean install
    cd target
    
  6. 빌드는 target 폴더의 .jar 파일을 provisioning-x509-sample-{version}-with-deps.jar 파일 형식으로 출력합니다. 예: provisioning-x509-sample-1.8.1-with-deps.jar. .jar 파일을 실행합니다. 다음 명령에서 버전을 바꿔야 할 수도 있습니다.

    java -jar ./provisioning-x509-sample-1.8.1-with-deps.jar
    

    샘플은 디바이스를 IoT 허브에 프로비전하는 DPS에 연결합니다. 디바이스가 프로비전된 후 샘플은 일부 테스트 메시지를 IoT Hub로 보냅니다.

    Starting...
    Beginning setup.
    WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
    2022-10-21 10:41:20,476 DEBUG (main) [com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient] - Initialized a ProvisioningDeviceClient instance using SDK version 2.0.2
    2022-10-21 10:41:20,479 DEBUG (main) [com.microsoft.azure.sdk.iot.provisioning.device.ProvisioningDeviceClient] - Starting provisioning thread...
    Waiting for Provisioning Service to register
    2022-10-21 10:41:20,482 INFO (global.azure-devices-provisioning.net-4f8279ac-CxnPendingConnectionId-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Opening the connection to device provisioning service...
    2022-10-21 10:41:20,652 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Connection to device provisioning service opened successfully, sending initial device registration message
    2022-10-21 10:41:20,680 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-RegisterTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.RegisterTask] - Authenticating with device provisioning service using x509 certificates
    2022-10-21 10:41:21,603 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Waiting for device provisioning service to provision this device...
    2022-10-21 10:41:21,605 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Current provisioning status: ASSIGNING
    2022-10-21 10:41:24,868 INFO (global.azure-devices-provisioning.net-4f8279ac-Cxn4f8279ac-azure-iot-sdk-ProvisioningTask) [com.microsoft.azure.sdk.iot.provisioning.device.internal.task.ProvisioningTask] - Device provisioning service assigned the device successfully
    IotHUb Uri : contoso-hub-2.azure-devices.net
    Device ID : device-01
    2022-10-21 10:41:30,514 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true
    2022-10-21 10:41:30,526 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true
    2022-10-21 10:41:30,533 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Initialized a DeviceClient instance using SDK version 2.1.2
    2022-10-21 10:41:30,590 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - Opening MQTT connection...
    2022-10-21 10:41:30,625 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT CONNECT packet...
    2022-10-21 10:41:31,452 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT CONNECT packet was acknowledged
    2022-10-21 10:41:31,453 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT SUBSCRIBE packet for topic devices/device-01/messages/devicebound/#
    2022-10-21 10:41:31,523 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT SUBSCRIBE packet for topic devices/device-01/messages/devicebound/# was acknowledged
    2022-10-21 10:41:31,525 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - MQTT connection opened successfully
    2022-10-21 10:41:31,528 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - The connection to the IoT Hub has been established
    2022-10-21 10:41:31,531 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Updating transport status to new status CONNECTED with reason CONNECTION_OK
    2022-10-21 10:41:31,532 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceIO] - Starting worker threads
    2022-10-21 10:41:31,535 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Invoking connection status callbacks with new status details
    2022-10-21 10:41:31,536 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Client connection opened successfully
    2022-10-21 10:41:31,537 INFO (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Device client opened successfully
    Sending message from device to IoT Hub...
    2022-10-21 10:41:31,539 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Message was queued to be sent later ( Message details: Correlation Id [0d143280-dbc7-405f-a61e-fcc7a1d80b87] Message Id [4d8d39c8-5a38-4299-8f07-3ae02cdc3218] )
    Press any key to exit...
    2022-10-21 10:41:31,540 DEBUG (contoso-hub-2.azure-devices.net-device-01-d7c67552-Cxn0bd73809-420e-46fe-91ee-942520b775db-azure-iot-sdk-IotHubSendTask) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Sending message ( Message details: Correlation Id [0d143280-dbc7-405f-a61e-fcc7a1d80b87] Message Id [4d8d39c8-5a38-4299-8f07-3ae02cdc3218] )
    2022-10-21 10:41:31,844 DEBUG (MQTT Call: device-01) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - IotHub message was acknowledged. Checking if there is record of sending this message ( Message details: Correlation Id [0d143280-dbc7-405f-a61e-fcc7a1d80b87] Message Id [4d8d39c8-5a38-4299-8f07-3ae02cdc3218] )
    2022-10-21 10:41:31,846 DEBUG (contoso-hub-2.azure-devices.net-device-01-d7c67552-Cxn0bd73809-420e-46fe-91ee-942520b775db-azure-iot-sdk-IotHubSendTask) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Invoking the callback function for sent message, IoT Hub responded to message ( Message details: Correlation Id [0d143280-dbc7-405f-a61e-fcc7a1d80b87] Message Id [4d8d39c8-5a38-4299-8f07-3ae02cdc3218] ) with status OK
    Message sent!
    
  7. 다음 표에 따라 두 번째 디바이스(device-02)에 대한 상수 업데이트, 다시 빌드 및 샘플을 다시 실행합니다.

    상수 사용할 파일
    leafPublicPem ./certs/device-02.cert.pem
    leafPrivateKey ./private/device-02.key.pem

디바이스 프로비저닝 등록 확인

등록 그룹의 등록 레코드를 검사하여 디바이스에 대한 등록 세부 정보를 확인합니다.

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

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

  3. 등록 그룹을 선택합니다. 이전에 만든 X.509 등록 그룹 항목이 목록에 나타나야 합니다.

  4. 등록 항목을 선택합니다. 그런 다음 등록 상태 옆에 있는 세부 정보를 선택하여 등록 그룹을 통해 등록된 디바이스를 확인합니다. 각 디바이스가 할당된 IoT Hub, 해당 디바이스 ID, 등록된 날짜 및 시간이 목록에 표시됩니다.

    Screenshot that shows the registration status details for the enrollment group on Azure portal.

  5. 디바이스 중 하나를 선택하여 해당 디바이스에 대한 자세한 정보를 볼 수 있습니다.

IoT 허브에서 디바이스를 확인하려면 다음을 수행합니다.

  1. Azure Portal에서 디바이스가 할당된 IoT Hub로 이동합니다.

  2. 디바이스 관리 메뉴에서 디바이스를 선택합니다.

  3. 디바이스가 성공적으로 프로비전된 경우 디바이스 ID( device-01device-02)가 목록에 표시되고 상태사용하도록 설정됩니다. 디바이스가 표시되지 않으면 새로 고침을 선택합니다.

    Screenshot that shows the devices are registered with the I o T hub in Azure portal.

리소스 정리

이 디바이스 클라이언트 샘플을 모두 테스트하고 탐색한 후에는 다음 단계에 따라 이 자습서에서 만든 모든 리소스를 삭제합니다.

  1. 컴퓨터에서 디바이스 클라이언트 샘플 출력 창을 닫습니다.

등록 그룹 삭제

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

  2. DPS 인스턴스를 선택합니다.

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

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

  5. 이 자습서에 사용한 등록 그룹을 선택합니다.

  6. 등록 세부 정보 페이지에서 등록 상태 옆에 있는 세부 정보를 선택합니다. 그런 다음 디바이스 ID 열 머리글 옆에 있는 확인란을 선택하여 등록 그룹에 대한 모든 등록 레코드를 선택합니다. 페이지 맨 위에서 삭제를 선택하여 등록 레코드를 삭제합니다.

    Important

    등록 그룹을 삭제해도 등록 그룹과 연결된 등록 레코드는 삭제되지 않습니다. 이러한 분리된 레코드는 DPS 인스턴스에 대한 등록 할당량에 대해 계산됩니다. 이러한 이유로 등록 그룹 자체를 삭제하기 전에 등록 그룹과 연결된 모든 등록 레코드를 삭제하는 것이 가장 좋습니다.

  7. 등록 관리 페이지로 돌아가서 등록 그룹 탭이 선택되어 있는지 확인합니다.

  8. 이 자습서에서 사용한 등록 그룹의 그룹 이름 옆에 있는 확인란을 선택합니다.

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

DPS에서 등록된 CA 인증서 삭제

  1. DPS instance 왼쪽 메뉴에서 인증서를 선택합니다. 이 자습서에서 업로드하고 확인한 각 인증서를 선택하고 삭제를 선택한 다음 삭제 결정을 확인하여 인증서를 제거합니다.

IoT Hub에서 디바이스 등록 삭제

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

  2. IoT Hub를 선택합니다.

  3. Explorers 메뉴에서 IoT 디바이스를 선택합니다.

  4. 이 자습서에서 등록한 디바이스의 디바이스 ID 옆에 있는 확인란을 선택합니다. 예를 들어 device-01device-02입니다.

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

다음 단계

이 자습서에서는 등록 그룹을 사용하여 여러 X.509 디바이스를 IoT 허브에 프로비전했습니다. 다음으로, 여러 허브에서 IoT 디바이스를 프로비전하는 방법을 알아봅니다.