分享方式:


如何透過不含 SDK 的 HTTPS 使用 X.509 憑證

在本操作說明文章中,您將在未使用 Azure IoT DPS 裝置 SDK 的情況下透過 HTTPS 使用 X.509 憑證來佈建裝置。 大部分的語言都提供程式庫來傳送 HTTP 要求,但在本文中 (而不是專注於某一個特定的語言),您將使用 cURL 命令列工具來透過 HTTPS 傳送和接收。

您可以在 Linux 或 Windows 機器上遵循本文中的步驟。 如果您在 Windows 子系統 Linux 版 (WSL) 上執行或在 Linux 機器上執行,則您可以在本機系統上的 Bash 提示字元中輸入所有命令。 如果您在 Windows 上執行,請在本機系統上的 GitBash 提示字元中輸入所有命令。

本文有多個路徑,視您選擇使用的註冊項目類型和 X.509 憑證而定。 在安裝必備項目之後,請務必先閱讀概觀,再繼續進行。

必要條件

  • 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

  • 完成透過 Azure 入口網站來設定 IoT 中樞裝置佈建服務中的步驟。

  • 請確定您已在電腦上安裝 Python 3.7 或更新版本。 您可以藉由執行 python --versionpython3 --version 來檢查您的 Python 版本。

  • 如果您是在 Windows 中執行,請安裝最新版的 Git。 確定 Git 已新增至可存取命令視窗的環境變數中。 請參閱 Software Freedom Conservancy 的 Git 用戶端工具以取得要安裝的最新版 git 工具,其中包括 Git Bash (您可用來與本機 Git 存放庫互動的命令列應用程式)。 在 Windows 上,您將在本機系統上的 GitBash 提示字元中輸入所有命令。

  • Azure CLI。 您有兩個選項可用來執行本文中的 Azure CLI 命令:

    • 使用 Azure Cloud Shell,這是一種在瀏覽器中執行 CLI 命令的互動式 shell。 建議使用此選項,因為您不需要安裝任何項目。 如果您是第一次使用 Cloud Shell,請登入 Azure 入口網站。 請遵循 Cloud Shell 快速入門中的步驟,以啟動 Cloud Shell選取 Bash 環境
    • 或者,在本機電腦上執行 Azure CLI。 如果已安裝 Azure CLI,請執行 az upgrade 以將 CLI 和擴充功能更新為目前的版本。 若要安裝 Azure CLI,請參閱安裝 Azure CLI
  • 如果您是在 Linux 或 WSL 環境中執行,請開啟 Bash 提示字元以在本機上執行命令。 如果您是在 Windows 環境中執行,請開啟 GitBash 提示字元。

概觀

本文涵蓋三種案例,您針對每個案例執行的初始步驟會有所不同。 如果要:

完成所選案例的步驟之後,您可以繼續進行註冊裝置傳送遙測訊息

建立裝置憑證

在本文中,您將運用 X.509 憑證,並使用個別註冊或註冊群組向 DPS 進行驗證。

如果您使用個別註冊,則可以使用自我簽署的 X.509 憑證或由裝置憑證組成的憑證鏈結加上一或多個簽署憑證。 如果您使用註冊群組,則必須使用憑證鏈結。

重要

針對 X.509 註冊驗證,會將裝置憑證的主體一般名稱 (CN) 作為裝置的註冊識別碼。 註冊識別碼是一組不區分大小寫的字串,由英數字元和 '-''.''_'':' 等特殊字元組成。 最後一個字元必須是英數字元或虛線 ('-')。 DPS 支援最多 128 個字元的註冊識別碼;不過,X.509 憑證中主體一般名稱限制為 64 個字元。 如果您在下列步驟中變更裝置憑證的主體一般名稱,請確定該名稱遵守此格式。

使用自我簽署憑證

若要建立與個別註冊搭配使用的自我簽署憑證,請瀏覽至您要建立憑證的目錄,並遵循下列步驟:

  1. 執行以下命令:

    winpty openssl req -outform PEM -x509 -sha256 -newkey rsa:4096 -keyout device-key.pem -out device-cert.pem -days 30 -extensions usr_cert -addext extendedKeyUsage=clientAuth -subj "//CN=my-x509-device"
    

    重要

    只需要針對主體名稱提供的額外正斜線 (//CN=my-x509-device) 以在 Windows 平台上使用 Git 逸出字串。

  2. 當系統要求您輸入 PEM 複雜密碼:時,請使用複雜密碼 1234

  3. 當系統要求驗證 - 輸入 PEM 複雜密碼:時,請再次使用複雜密碼 1234

    裝置憑證檔案 (device-cert.pem) 和私密金鑰檔案 (device-key.pem) 現在應該會在您執行 openssl 命令的目錄中產生。

    憑證檔案的主體一般名稱 (CN) 設定為 my-x509-device

    私密金鑰檔案受到複雜密碼保護:1234

  4. 憑證檔案為 Base64 編碼。 若要檢視主體一般名稱 (CN) 和其他憑證檔案的屬性,請輸入下列命令:

    winpty openssl x509 -in device-cert.pem -text -noout
    
    Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            77:3e:1d:e4:7e:c8:40:14:08:c6:09:75:50:9c:1a:35:6e:19:52:e2
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = my-x509-device
        Validity
            Not Before: May  5 21:41:42 2022 GMT
            Not After : Jun  4 21:41:42 2022 GMT
        Subject: CN = my-x509-device
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (4096 bit)
                Modulus:
                    00:d2:94:37:d6:1b:f7:43:b4:21:c6:08:1a:d6:d7:
                    e6:40:44:4e:4d:24:41:6c:3e:8c:b2:2c:b0:23:29:
                    ...
                    23:6e:58:76:45:18:03:dc:2e:9d:3f:ac:a3:5c:1f:
                    9f:66:b0:05:d5:1c:fe:69:de:a9:09:13:28:c6:85:
                    0e:cd:53
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                63:C0:B5:93:BF:29:F8:57:F8:F9:26:44:70:6F:9B:A4:C7:E3:75:18
            X509v3 Authority Key Identifier:
                keyid:63:C0:B5:93:BF:29:F8:57:F8:F9:26:44:70:6F:9B:A4:C7:E3:75:18
    
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
    Signature Algorithm: sha256WithRSAEncryption
         82:8a:98:f8:47:00:85:be:21:15:64:b9:22:b0:13:cc:9e:9a:
         ed:f5:93:b9:4b:57:0f:79:85:9d:89:47:69:95:65:5e:b3:b1:
         ...
         cc:b2:20:9a:b7:f2:5e:6b:81:a1:04:93:e9:2b:92:62:e0:1c:
         ac:d2:49:b9:36:d2:b0:21
    

使用憑證鏈結

如果您使用註冊群組,則必須使用憑證鏈結進行驗證。 透過個別註冊,您可以使用憑證鏈結或自我簽署憑證。

若要建立憑證鏈結,請遵循建立 X.509 憑證鏈結中的指示。 您只需要本文的一個裝置,因此可以在建立第一個裝置的私密金鑰和憑證鏈結之後停止。

當您完成時,應該會有下列檔案:

憑證 檔案 說明
根 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.cert.pem 用來使用 DPS 建立個別註冊項目。
device-01 完整鏈結憑證 certs/device-01-full-chain.cert.pem 由裝置呈現,以向 DPS 進行驗證和註冊。

使用個別註冊

若要建立用於本文的個別註冊,請使用 az iot dps enrollment create 命令。

下列命令會使用您指定的裝置憑證,為您的 DPS 執行個體建立具有預設配置原則的個別註冊項目。

az iot dps enrollment create -g {resource_group_name} --dps-name {dps_name} --enrollment-id {enrollment_id} --attestation-type x509 --certificate-path {path to your certificate}
  • 替換您的資源群組和 DPS 執行個體的名稱。

  • 註冊識別碼是您裝置的註冊識別碼,X.509 註冊必須符合裝置憑證的主體一般名稱 (CN)。

  • 憑證路徑是您裝置憑證的路徑。

注意

如果您使用 Cloud Shell 來執行 Azure CLI 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。

顯示 Azure Cloud Shell 中上傳檔案按鈕的螢幕快照。

使用註冊群組

若要建立用於本文的註冊群組,請使用 az iot dps enrollment-group create 命令。

下列命令會使用中繼 CA 憑證,為您的 DPS 執行個體建立具有預設配置原則的註冊群組項目:

az iot dps enrollment-group create -g {resource_group_name} --dps-name {dps_name} --enrollment-id {enrollment_id} --certificate-path {path_to_your_certificate}
  • 替換您的資源群組和 DPS 執行個體的名稱。

  • 註冊識別碼是一組不區分大小寫的字串,由英數字元和 '-''.''_'':' 等特殊字元組成。 最後一個字元必須是英數字元或虛線 ('-')。 這可以是您選擇要用於註冊群組的任何名稱。

  • 憑證路徑是您中繼憑證的路徑。 如果您遵循使用憑證鏈結中的指示,則檔案名為 certs/azure-iot-test-only.intermediate.cert.pem

注意

如果您使用 Cloud Shell 來執行 Azure CLI 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。

顯示 Azure Cloud Shell 中上傳檔案按鈕的螢幕快照。

注意

如果您想要的話,您可以根據先前上傳並驗證 DPS 的簽署憑證來建立註冊群組 (請參閱下一節)。 若要這樣做,請使用 --ca-name 指定憑證名稱,並省略 az iot dps enrollment-group create 命令中的 --certificate-path 參數。

上傳並驗證簽署憑證

如果您針對個別註冊或註冊群組使用憑證鏈結,則必須將裝置憑證簽署鏈結中的至少一個憑證上傳並驗證至 DPS。

  • 針對個別註冊,這可以是裝置憑證鏈結中的任何簽署憑證。

  • 對於註冊群組,這可以是在註冊群組上設定的憑證,或是其註冊鏈結中的任何憑證,包含根 CA 憑證。

若要上傳並驗證您的憑證,請使用 az iot dps certificate create 命令:

az iot dps certificate create -g {resource_group_name} --dps-name {dps_name} --certificate-name {friendly_name_for_your_certificate} --path {path_to_your_certificate} --verified true
  • 替換您的資源群組和 DPS 執行個體的名稱。

  • 憑證路徑是您簽署憑證的路徑。 在本文中,建議您上傳根 CA 憑證。 如果您遵循使用憑證鏈結中的指示,則檔案名為 certs/azure-iot-test-only.root.ca.cert.pem

  • 憑證名稱只能包含英數字元或下列特殊字元:-._。 不允許空白字元。 例如,「azure-iot-test-only-root」。

注意

如果您使用 Cloud Shell 來執行 Azure CLI 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。

顯示 Azure Cloud Shell 中上傳檔案按鈕的螢幕快照。

注意

本節中的步驟會自動驗證上傳憑證。 您也可以手動驗證憑證。 若要深入了解,請參閱手動驗證中繼或根 CA

登記裝置

您可以呼叫 Register Device REST API 來透過 DPS 佈建您的裝置。

使用下列的 curl 命令:

curl -L -i -X PUT --cert [path_to_your_device_cert] --key [path_to_your_device_private_key] -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[dps_id_scope]/registrations/[registration_id]/register?api-version=2019-03-31

其中:

  • -L 告知 curl 遵循 HTTP 重新導向。

  • –i 告知 curl 在輸出中包括通訊協定標頭。 這些標頭並非絕對必要,但它們可能很有用。

  • -X PUT 告知 curl 這是 HTTP PUT 命令。 此 API 呼叫需要。

  • --cert [path_to_your_device_cert] 告知 curl 哪裡可以找到您裝置的 X.509 憑證。 如果您的裝置私密金鑰受到複雜密碼保護,您可以在憑證路徑前面加上冒號,例如:--cert my-device.pem:1234

    • 如果您使用自我簽署憑證,您的裝置憑證檔案只會包含單一 X.509 憑證。 如果您遵循使用自我簽署憑證中的指示,則檔案名為 device-cert.pem,私密金鑰複雜密碼為 1234,因此請使用 --cert device-cert.pem:1234

    • 例如,如果您使用憑證鏈結,例如,透過註冊群組進行驗證時,您的裝置憑證檔案必須包含有效的憑證鏈結。 憑證鏈結必須包含裝置憑證,以及任何簽署憑證,包含已驗證憑證。 如果您遵循使用憑證鏈結建立憑證鏈結中的指示,則檔案路徑為 certs/device-01-full-chain.cert.pem,因此請使用 --cert certs/device-01-full-chain.cert.pem

  • --key [path_to_your_device_private_key] 告知 curl 尋找您裝置的私密金鑰位置。

    • 如果您遵循使用自我簽署憑證中的指示,則檔案名為 device-key.pem,因此請使用 --key device-cert.pem:1234

    • 如果您遵循使用憑證鏈結中的指示,則檔案路徑為 certs/device-01-full-chain.cert.pem,因此請使用 --cert certs/device-01-full-chain.cert.pem

  • -H 'Content-Type: application/json' 告知 DPS 我們正在張貼 JSON 內容,而且必須是 'application/json'

  • -H 'Content-Encoding: utf-8' 告知 DPS 我們用於訊息本文的編碼方式。 針對您的 OS/用戶端設為適當的值;不過,該值通常是 utf-8

  • -d '{"registrationId": "[registration_id]"}'–d 參數是我們張貼訊息的「資料」或本文。 其必須是 JSON,格式為 '{"registrationId":"[registration_id"}'。 請注意,對於 curl,其會以單引號括住;否則,您必須逸出 JSON 中的雙引號。 對於 X.509 註冊,註冊識別碼是裝置憑證的主體一般名稱 (CN)。

  • 最終,最後一個參數是要張貼的 URL。 對於「一般」(亦即非內部部署) DPS,則會使用全域 DPS 端點 global.azure-devices-provisioning.nethttps://global.azure-devices-provisioning.net/[dps_id_scope]/registrations/[registration_id]/register?api-version=2019-03-31。 請注意,您必須以適當的值來取代 [dps_scope_id][registration_id]

例如:

  • 如果您遵循使用自我簽署憑證中的指示:

    curl -L -i -X PUT --cert device-cert.pem:1234 --key device-key.pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"registrationId": "my-x509-device"}' https://global.azure-devices-provisioning.net/0ne00111111/registrations/my-x509-device/register?api-version=2021-06-01
    
  • 如果您遵循使用憑證鏈結中的指示:

    curl -L -i -X PUT --cert certs/device-01-full-chain.cert.pem --key private/device-01.key.pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"registrationId": "device-01"}' https://global.azure-devices-provisioning.net/0ne00111111/registrations/device-01/register?api-version=2021-06-01
    

成功的呼叫會有類似下列的回應:

HTTP/1.1 202 Accepted
Date: Sat, 27 Aug 2022 17:53:18 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Location: https://global.azure-devices-provisioning.net/0ne00111111/registrations/my-x509-device/register
Retry-After: 3
x-ms-request-id: 05cdec07-c0c7-48f3-b3cd-30cfe27cbe57
Strict-Transport-Security: max-age=31536000; includeSubDomains

{"operationId":"5.506603669bd3e2bf.b3602f8f-76fe-4341-9214-bb6cfb891b8a","status":"assigning"}

該回應包含作業識別碼和狀態。 在此情況下,狀態會設定為 assigning。 DPS 註冊可能是一項長時間執行的作業,因此會以非同步的方式來完成。 一般而言,您將使用 Operation Status Lookup REST API 來輪詢狀態,以判斷裝置是否已指派或是否發生失敗問題。

DPS 的有效狀態值為:

  • assigned:來自狀態呼叫的傳回值會指出裝置被指派到哪個 IoT 中樞。

  • assigning:作業仍在執行中。

  • disabled:註冊記錄已在 DPS 中停用,因此無法指派裝置。

  • failed:指派失敗。 將會在回應的 registrationState 記錄中傳回 errorCodeerrorMessage,以指出什麼失敗了。

  • unassigned

若要呼叫 Operation Status Lookup API,請使用下列 curl 命令:

curl -L -i -X GET --cert [path_to_your_device_cert] --key [path_to_your_device_private_key] -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' https://global.azure-devices-provisioning.net/[dps_id_scope]/registrations/[registration_id]/operations/[operation_id]?api-version=2019-03-31

您將使用與在 Register Device 要求中使用相同的識別碼範圍、註冊識別碼和憑證與金鑰。 使用 Register Device 回應中已傳回的作業識別碼。

例如,下列命令適用於使用自我簽署憑證中所建立的自我簽署憑證。 (您必須修改識別碼範圍和作業識別碼。)

curl -L -i -X GET --cert ./device-certPUT --cert device-cert.pem:1234 --key device-key.pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' https://global.azure-devices-provisioning.net/0ne00111111/registrations/my-x509-device/operations/5.506603669bd3e2bf.b3602f8f-76fe-4341-9214-bb6cfb891b8a?api-version=2021-06-01

下列輸出顯示已成功指派裝置的回應。 請注意,status 屬性是 assigned,而 registrationState.assignedHub 屬性會設為在其中佈建裝置的 IoT 中樞。

HTTP/1.1 200 OK
Date: Sat, 27 Aug 2022 18:10:49 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
x-ms-request-id: 8f211bc5-3ed8-4c8b-9a79-e003e756e9e4
Strict-Transport-Security: max-age=31536000; includeSubDomains

{
   "operationId":"5.506603669bd3e2bf.b3602f8f-76fe-4341-9214-bb6cfb891b8a",
   "status":"assigned",
   "registrationState":{
      "x509":{
         
      },
      "registrationId":"my-x509-device",
      "createdDateTimeUtc":"2022-08-27T17:53:19.5143497Z",
      "assignedHub":"MyExampleHub.azure-devices.net",
      "deviceId":"my-x509-device",
      "status":"assigned",
      "substatus":"initialAssignment",
      "lastUpdatedDateTimeUtc":"2022-08-27T17:53:19.7519141Z",
      "etag":"IjEyMDA4NmYyLTAwMDAtMDMwMC0wMDAwLTYzMGE1YTBmMDAwMCI="
   }
}

記下裝置識別碼和指派的 IoT 中樞。 您將在下一節使用這些項目來傳送遙測訊息。

傳送遙測訊息

您可以呼叫 IoT Hub Send Device Event REST API,以將遙測傳送至裝置。

使用下列的 curl 命令:

curl -L -i -X POST --cert [path_to_your_device_cert] --key [path_to_your_device_private_key] -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"temperature": 30}' https://[assigned_iot_hub_name].azure-devices.net/devices/[device_id]/messages/events?api-version=2020-03-13

其中:

  • -X POST 告知 curl 這是 HTTP POST 命令。 此 API 呼叫需要。

  • --cert [path_to_your_device_cert] 告知 curl 哪裡可以找到您裝置的 X.509 憑證。 如果您的裝置私密金鑰受到複雜密碼保護,您可以在憑證路徑前面加上冒號,例如:--cert my-device.pem:1234

    • 如果您使用自我簽署憑證,您的裝置憑證檔案只會包含單一 X.509 憑證。 如果您遵循使用自我簽署憑證中的指示,則檔案名為 device-cert.pem,私密金鑰複雜密碼為 1234,因此請使用 --cert device-cert.pem:1234

    • 如果您使用憑證鏈結,則您的裝置憑證檔案必須包含有效的憑證鏈結。 如果您遵循使用憑證鏈結建立憑證鏈結中的指示,則檔案路徑為 certs/device-01-full-chain.cert.pem,因此請使用 --cert certs/device-01-full-chain.cert.pem

  • --key [path_to_your_device_private_key] 告知 curl 尋找您裝置的私密金鑰位置。

    • 如果您遵循使用自我簽署憑證中的指示,則檔案名為 device-key.pem,因此請使用 --key device-cert.pem:1234

    • 如果您遵循使用憑證鏈結中的指示,則檔案路徑為 certs/device-01-full-chain.cert.pem,因此請使用 --cert certs/device-01-full-chain.cert.pem

  • -H 'Content-Type: application/json' 告知 IoT 中樞我們正在張貼 JSON 內容,而且必須是 'application/json'。

  • -H 'Content-Encoding: utf-8' 告知 IoT 中樞我們用於訊息本文的編碼方式。 針對您的 OS/用戶端設為適當的值;不過,該值通常是 utf-8

  • -d '{"temperature": 30}'–d 參數是我們張貼訊息的「資料」或本文。 對於本文,我們會張貼一個單一的溫度資料點。 內容類型已指定為 application/json,所以對於此要求,本文為 JSON。 請注意,對於 curl,其會以單引號括住;否則,您必須逸出 JSON 中的雙引號。

  • 最後一個參數是要張貼的 URL。 對於 Send Device Event API,URL 為:https://[assigned_iot_hub_name].azure-devices.net/devices/[device_id]/messages/events?api-version=2020-03-13

    • [assigned_iot_hub_name] 取代為將您的裝置指派到其中的 IoT 中樞名稱。

    • [device_id] 取代為您登錄裝置時所指派的裝置識別碼。 對於透過註冊群組所佈建的裝置,裝置識別碼會是登錄識別碼。 對於個別註冊,您可以選擇性地指定與註冊項目中登錄識別碼不同的裝置識別碼。

例如:

  • 如果您遵循使用自我簽署憑證中的指示:

    curl -L -i -X POST --cert device-cert.pem:1234 --key device-key.pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"temperature": 30}' https://MyExampleHub.azure-devices.net/devices/my-x509-device/messages/events?api-version=2020-03-13
    
  • 如果您遵循使用憑證鏈結中的指示:

    curl -L -i -X POST --cert certs/device-01-full-chain.cert.pem --key private/device-01.key.pem -H 'Content-Type: application/json' -H 'Content-Encoding:  utf-8' -d '{"temperature": 30}' https://MyExampleHub.azure-devices.net/devices/my-x509-device/messages/events?api-version=2020-03-13
    

成功的呼叫會有類似下列的回應:

HTTP/1.1 204 No Content
Content-Length: 0
Vary: Origin
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: aa58c075-20d9-4565-8058-de6dc8524f14
Date: Wed, 31 Aug 2022 18:34:44 GMT

後續步驟