如何透過不含 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 訂用帳戶,請在開始前建立免費帳戶。
請確定您已在電腦上安裝 Python 3.7 或更新版本。 您可以藉由執行
python --version
或python3 --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 個字元。 如果您在下列步驟中變更裝置憑證的主體一般名稱,請確定該名稱遵守此格式。
使用自我簽署憑證
若要建立與個別註冊搭配使用的自我簽署憑證,請瀏覽至您要建立憑證的目錄,並遵循下列步驟:
執行以下命令:
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 逸出字串。當系統要求您輸入 PEM 複雜密碼:時,請使用複雜密碼
1234
。當系統要求驗證 - 輸入 PEM 複雜密碼:時,請再次使用複雜密碼
1234
。裝置憑證檔案 (device-cert.pem) 和私密金鑰檔案 (device-key.pem) 現在應該會在您執行
openssl
命令的目錄中產生。憑證檔案的主體一般名稱 (CN) 設定為
my-x509-device
。私密金鑰檔案受到複雜密碼保護:
1234
。憑證檔案為 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 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。
使用註冊群組
若要建立用於本文的註冊群組,請使用 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 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。
注意
如果您想要的話,您可以根據先前上傳並驗證 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 命令,您可以在執行命令前使用 [上傳] 按鈕將憑證檔案上傳至雲端磁碟機。
注意
本節中的步驟會自動驗證上傳憑證。 您也可以手動驗證憑證。 若要深入了解,請參閱手動驗證中繼或根 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 尋找您裝置的私密金鑰位置。-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.net:
https://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
記錄中傳回errorCode
及errorMessage
,以指出什麼失敗了。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 尋找您裝置的私密金鑰位置。-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
後續步驟
若要深入了解 X.509 憑證的證明,請參閱 X.509 憑證證明。
若要深入了解上傳和驗證 X.509 憑證,請參閱設定已驗證的 CA 憑證。