某些開發情境 (例如 OTA 測試) 需要建立非實際工作環境 Matter 憑證。
Google 生態系統的部分功能 (包括裝置 OTA 軟體更新) 無法使用測試 VID/PID 執行。
本指南說明如何建立及驗證非正式發布版 Matter 憑證,以便用於測試。憑證類型如下:
- 認證聲明 (CD)
- 產品認證中繼憑證 (PAI)
- 裝置認證憑證 (DAC)
在調試過程中,Matter 認證裝置需要認證自身,也就是證明自己是正版的 Matter 認證產品。Matter 裝置用於認證的憑證包括:
- 認證金鑰組
- 憑證鏈結
裝置認證憑證 (DAC) 是憑證鏈結的第一個連結,並由產品認證中介憑證 (PAI) 驗證,而後者則由產品認證機構 (PAA) 驗證。
憑證會在產生認證金鑰組時簽署,並使用上一層憑證授權單位的私密金鑰簽署,形成信任鏈。因此,DAC 憑證會由 PAI 金鑰簽署,而 PAI 憑證則由 PAA 金鑰簽署。由於 PAA 憑證位於鏈結頂端,因此是自行簽署的憑證。這個信任鏈結會形成聯合 PAA 結構,並由分散式法規遵循總帳 (DCL) 進行同步處理。
如要進一步瞭解認證程序和認證聲明 (CD),請參閱「其他認證文件和訊息」和「Matter 規格」。
安裝 Matter SDK
這些操作說明假設您已安裝可正常運作的 Matter SDK。如需更多資訊,請參閱 Github 上的說明文件,或參閱「開始使用 Matter」一文。
如果您沒有 hexdump 公用程式 xxd
,請先安裝。這項工具可用於以 C 樣式格式列印憑證:
sudo apt-get install xxd
建構作業「chip-cert
」
請確認您使用的是最新版本的 SDK。這些程序已在
v1.0-branch
分支的 GitHub SHA0b17bce8
上進行測試:$ cd connectedhomeip $ git checkout v1.0-branch $ git pull
建構
chip-cert
,這是用於對 Matter 裝置憑證執行多項作業的工具:設定建構作業:
$ cd src/credentials $ source ../../scripts/activate.sh $ gn gen out
gn
輸出內容範例:Done. Made 5774 targets from 289 files in 658ms
執行版本:
$ ninja -C out
ninja
輸出內容範例:ninja: Entering directory `out' [2000/2000] stamp obj/default.stamp
發行憑證
將自訂 VID/PID 匯出為環境變數,以減少編輯指令引數時發生文書錯誤的機會:
$ cd ../..
$ export VID=hexVendorId
$ export PID=hexProductId
產生 CD
使用
chip-cert
產生 CD。目前,監管機構只會驗證 VID 和 PID 是否與裝置在其他位置公開的資料相符,包括基本資訊叢集、DAC 和 DAC 來源 (如果有)。您可以將其他欄位保持不變:$ src/credentials/out/chip-cert gen-cd \ --key credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem \ --cert credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem \ --out credentials/test/certification-declaration/Chip-Test-CD-${VID}-${PID}.der \ --format-version "1" \ --vendor-id "${VID}" \ --product-id "${PID}" \ --device-type-id "0x1234" \ --certificate-id "ZIG20141ZB330001-24" \ --security-level "0" \ --security-info "0" \ --version-number "9876" \ --certification-type "0"
驗證 CD。請確認該檔案包含 VID/PID (以十進位格式表示):
$ src/credentials/out/chip-cert print-cd credentials/test/certification-declaration/Chip-Test-CD-${VID}-${PID}.der
輸出內容範例:
SignerKeyId value: hex:62FA823359ACFAA9963E1CFA140ADDF504F37160 0x01, tag[Anonymous]: 0xffffffff, type: Structure (0x15), container: 0x04, tag[Context Specific]: 0x0, type: Unsigned Fixed Point (0x04), value: 1 0x08, tag[Context Specific]: 0x1, type: Unsigned Fixed Point (0x04), value: XXXXX // <- VID 0x0A, tag[Context Specific]: 0x2, type: Array (0x16), container: 0x0D, tag[Anonymous]: 0xffffffff, type: Unsigned Fixed Point (0x04), value: XXXXX // <- PID 0x12, tag[Context Specific]: 0x3, type: Unsigned Fixed Point (0x04), value: 4660 0x15, tag[Context Specific]: 0x4, type: UTF-8 String (0x0c), length: 19, value: "ZIG20141ZB330001-24" 0x2B, tag[Context Specific]: 0x5, type: Unsigned Fixed Point (0x04), value: 0 0x2E, tag[Context Specific]: 0x6,type: Unsigned Fixed Point (0x04), value: 0 0x32, tag[Context Specific]: 0x7, type: Unsigned Fixed Point (0x04), value: 39030 0x35, tag[Context Specific]: 0x8, type: Unsigned Fixed Point (0x04), value: 0
產生 PAI 和 DAC
在本例中,我們會使用 Matter 的測試產品認證授權單位 (PAA) 憑證和簽署金鑰 Chip-Test-PAA-NoVID
做為根憑證。我們會將其用作根 CA,產生自己的 PAI 和 DAC。
使用 PAA 產生 PAI。您可以選擇在 PAI 中加入 PID 資訊,但省略這項資訊可讓測試更具彈性。如果需要其他 PID 的 DAC,您可以只執行 DAC 產生步驟:
$ src/credentials/out/chip-cert gen-att-cert --type i \ --subject-cn "Matter Test PAI" \ --subject-vid "${VID}" \ --valid-from "2021-06-28 14:23:43" \ --lifetime "4294967295" \ --ca-key credentials/test/attestation/Chip-Test-PAA-NoVID-Key.pem \ --ca-cert credentials/test/attestation/Chip-Test-PAA-NoVID-Cert.pem \ --out-key credentials/test/attestation/"test-PAI-${VID}-key".pem \ --out credentials/test/attestation/"test-PAI-${VID}-cert".pem
使用 PAI 產生 DAC:
$ src/credentials/out/chip-cert gen-att-cert --type d \ --subject-cn "Matter Test DAC 0" \ --subject-vid "${VID}" \ --subject-pid "${PID}" \ --valid-from "2021-06-28 14:23:43" \ --lifetime "4294967295" \ --ca-key credentials/test/attestation/"test-PAI-${VID}-key".pem \ --ca-cert credentials/test/attestation/"test-PAI-${VID}-cert".pem \ --out-key credentials/test/attestation/"test-DAC-${VID}-${PID}-key".pem \ --out credentials/test/attestation/"test-DAC-${VID}-${PID}-cert".pem
驗證 DAC、PAI 和 PAA 鏈結。如果輸出內容中沒有顯示任何錯誤,表示憑證認證鏈已成功驗證:
$ src/credentials/out/chip-cert validate-att-cert \ --dac credentials/test/attestation/"test-DAC-${VID}-${PID}-cert".pem \ --pai credentials/test/attestation/"test-PAI-${VID}-cert".pem \ --paa credentials/test/attestation/Chip-Test-PAA-NoVID-Cert.pem
您可以使用
openssl
檢查金鑰:$ openssl ec -noout -text -in \ credentials/test/attestation/test-DAC-${VID}-${PID}-key.pem
輸出內容範例:
read EC key Private-Key: (256 bit) priv: c9:f2:b3:04:b2:db:0d:6f:cd:c6:be:f3:7b:76:8d: 8c:01:4e:0b:9e:ce:3e:72:49:3c:0e:35:63:7c:6c: 6c:d6 pub: 04:4f:93:ba:3b:bf:63:90:73:98:76:1e:af:87:79: 11:e6:77:e8:e2:df:a7:49:f1:7c:ac:a8:a6:91:76: 08:5b:39:ce:6c:72:db:6d:9a:92:b3:ba:05:b0:e8: 31:a0:bf:36:50:2b:5c:72:55:7f:11:c8:01:ff:3a: 46:b9:19:60:28 ASN1 OID: prime256v1 NIST CURVE: P-256
您也可以使用
openssl
檢查產生的憑證:$ openssl x509 -noout -text -in \ credentials/test/attestation/test-DAC-${VID}-${PID}-cert.pem
輸出內容範例:
Certificate: Data: Version: 3 (0x2) Serial Number: 2875998130766646679 (0x27e9990fef088d97) Signature Algorithm: ecdsa-with-SHA256 Issuer: CN = Matter Test PAI, 1.3.6.1.4.1.37244.2.1 = hexVendorId Validity Not Before: Jun 28 14:23:43 2021 GMT Not After : Dec 31 23:59:59 9999 GMT Subject: CN = Matter Test DAC 0, 1.3.6.1.4.1.37244.2.1 = hexVendorId, 1.3.6.1.4.1.37244.2.2 = hexProductId Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:4f:93:ba:3b:bf:63:90:73:98:76:1e:af:87:79: 11:e6:77:e8:e2:df:a7:49:f1:7c:ac:a8:a6:91:76: 08:5b:39:ce:6c:72:db:6d:9a:92:b3:ba:05:b0:e8: 31:a0:bf:36:50:2b:5c:72:55:7f:11:c8:01:ff:3a: 46:b9:19:60:28 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: critical Digital Signature X509v3 Subject Key Identifier: 21:0A:CA:B1:B6:5F:17:65:D8:61:19:73:84:1A:9D:52:81:19:C5:39 X509v3 Authority Key Identifier: 37:7F:24:9A:73:41:4B:16:6E:6A:42:6E:F5:E8:89:FB:75:F8:77:BB Signature Algorithm: ecdsa-with-SHA256 Signature Value: 30:45:02:20:38:8f:c5:0d:3e:90:95:dd:7d:7c:e9:5a:05:19: 1f:2d:14:08:a3:d7:0e:b5:15:6d:d3:b0:0b:f7:b8:28:4d:bf: 02:21:00:d4:05:30:43:a6:05:00:0e:b9:99:0d:34:3d:75:fe: d3:c1:4e:73:ff:e7:05:64:7a:62:8d:2d:38:8f:fd:4d:ad
PAA
您可以使用類似的程序產生自行簽署的 PAA,但這並非必要。
我們在此處採用的做法是使用現有的自行簽署開發 PAA,不含 VID 資訊。
如需產生 CD 的更多範例,請參閱 credentials/test/gen-test-cds.sh
。如需產生 PAA、PAI 和 DAC 的更多範例,請參閱 credentials/test/gen-test-attestation-certs.sh
。
更換憑證
取代 PAA 和 PAI
- 執行下列輔助指令碼,該指令碼會使用 CHIP 憑證工具 (
chip-cert
) 產生 C 樣式陣列的憑證。
#!/bin/bash # # generate-embeddable-certs.sh script # —---------------------------------- # # This script generates self-minted DAC and PAI. # The output may easily be included in your C++ source code. # # Edit this information with your paths and certificates folder="credentials/test/attestation" chip_cert_tool="src/credentials/out/chip-cert" cert_file_der="${folder}/test-PAI-${VID}-cert.der" cert_file_pem="${folder}/test-PAI-${VID}-cert.pem" key_file_pem="${folder}/test-PAI-${VID}-key.pem" type="Pai" printf "namespace chip {\n" printf "namespace DevelopmentCerts {\n\n" printf "#if CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID == ${PID}\n\n" printcert() { # convert cert to DER if [ -f "${cert_file_der}" ]; then rm "${cert_file_der}" fi "${chip_cert_tool}" convert-cert "${cert_file_pem}" "${cert_file_der}" --x509-der printf "// ------------------------------------------------------------ \n" printf "// ${type} CERTIFICATE ${cert_file_der} \n\n" printf "constexpr uint8_t ${type}_Cert_Array[] = {\n" less -f "${cert_file_der}" | od -t x1 -An | sed 's/\0x/g' | sed 's/\>/,/g' | sed 's/^/ /g' printf "};\n\n" printf "ByteSpan k${type}Cert = ByteSpan(${type}_Cert_Array);\n\n" printf "// ${type} PUBLIC KEY FROM ${key_file_pem} \n\n" printf "constexpr uint8_t ${type}_PublicKey_Array[] = {\n" openssl ec -text -noout -in "${key_file_pem}" 2>/dev/null | sed '/ASN1 OID/d' | sed '/NIST CURVE/d' | sed -n '/pub:/,$p' | sed '/pub:/d' | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)/0x\1/g' | sed 's/:/, /g' printf "};\n\n" printf "ByteSpan k${type}PublicKey = ByteSpan(${type}_PublicKey_Array);\n\n" printf "// ${type} PRIVATE KEY FROM ${key_file_pem} \n\n" printf "constexpr uint8_t ${type}_PrivateKey_Array[] = {\n" openssl ec -text -noout -in "${key_file_pem}" 2>/dev/null | sed '/read EC key/d' | sed '/Private-Key/d' | sed '/priv:/d' | sed '/pub:/,$d' | sed 's/\([0-9a-fA-F][0-9a-fA-F]\)/0x\1/g' | sed 's/:/, /g' printf "};\n\n" printf "ByteSpan k${type}PrivateKey = ByteSpan(${type}_PrivateKey_Array);\n\n" } # generates PAI printcert type="Dac" cert_file_der="${folder}/test-DAC-${VID}-${PID}-cert.der" cert_file_pem="${folder}/test-DAC-${VID}-${PID}-cert.pem" key_file_pem="${folder}/test-DAC-${VID}-${PID}-key.pem" # generates DAC printcert printf "#endif // CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID\n" printf "} // namespace DevelopmentCerts\n" printf "} // namespace chip\n"
將 PAI 和 DAC 輸出的內容複製到
DeviceAttestationCredentialsProvider::GetProductAttestationIntermediateCert
的實作項目。在實際生產的裝置上,PAI 和 DAC 會位於「Factory Data」中,而 CD 則會嵌入韌體本身。
如果您尚未使用 Factory Data,建議您將 PAI 放在
src/credentials/examples/ExampleDACs.cpp
中。在這種情況下,請將產生的結果程式碼附加至ExampleDACs.cpp
檔案:ByteSpan kDacCert = ByteSpan(kDevelopmentDAC_Cert_FFF1_801F); ByteSpan kDacPrivateKey = ByteSpan(kDevelopmentDAC_PrivateKey_FFF1_801F); ByteSpan kDacPublicKey = ByteSpan(kDevelopmentDAC_PublicKey_FFF1_801F); #endif } // namespace DevelopmentCerts } // namespace chip /* ------------------------------------------ */ /* current end-of-file */ /* ------------------------------------------ */ /* ------------------------------------------ */ /* output of creds-codelab.sh script */ /* ------------------------------------------ */ namespace chip { namespace DevelopmentCerts { #if CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID == hexProductId ... ByteSpan kDacPrivateKey = ByteSpan(Dac_PrivateKey_Array); #endif // CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID } // namespace DevelopmentCerts } // namespace chip
如果您使用工廠資料或自訂憑證提供者,請務必在適當位置插入憑證。建議您向 SoC 供應商洽詢平台的具體資訊。
更換 CD
使用
xxd
擷取 CD 檔案內容的文字表示法:$ xxd -i credentials/test/certification-declaration/Chip-Test-CD-${VID}-${PID}.der
輸出內容範例:
unsigned char credentials_test_certification_declaration_Chip_Test_CD_hexVendorId_hexProductId_der[] = { 0x30, 0x81, 0xe9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xdb, 0x30, 0x81, 0xd8, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x45, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x38, 0x04, 0x36, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xfe, 0xca, 0x36, 0x02, 0x05, 0xce, 0xfa, 0x18, 0x25, 0x03, 0x34, 0x12, 0x2c, 0x04, 0x13, 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x31, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2d, 0x32, 0x34, 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x53, 0x25, 0x03, 0x2c, 0x96, 0x50, 0xb6, 0x64, 0xf4, 0x18, 0xbf, 0x99, 0x47, 0xf8, 0x9d, 0xe6, 0xeb, 0x43, 0x94, 0xf1, 0xce, 0xb2, 0x61, 0x00, 0xe0, 0xf9, 0x89, 0xa8, 0x71, 0x82, 0x02, 0x0a, 0x02, 0x21, 0x00, 0xea, 0x0a, 0x40, 0xab, 0x87, 0xad, 0x7e, 0x25, 0xe1, 0xa1, 0x6c, 0xb1, 0x12, 0xfa, 0x86, 0xfe, 0xea, 0x8a, 0xaf, 0x4b, 0xc1, 0xf3, 0x6f, 0x09, 0x85, 0x46, 0x50, 0xb6, 0xd0, 0x55, 0x40, 0xe2 }; unsigned int credentials_test_certification_declaration_Chip_Test_CD_hexVendorId_hexProductId_der_len = 236; ```
將上一個步驟中擷取的文字複製到用於在建構中定義 CD 的檔案中。如同 PAI 和 DAC 的情況,這項操作方式取決於您在哪個平台上進行開發。
如果您使用憑證範例,建議您在 src/credentials/examples/DeviceAttestationCredsExample.cpp
中,將 ExampleDACProvider::GetCertificationDeclaration
中的 kCdForAllExamples
內容替換為:
const uint8_t kCdForAllExamples[] = {
0x30, 0x81, 0xe9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x07, 0x02, 0xa0, 0x81, 0xdb, 0x30, 0x81, 0xd8, 0x02, 0x01, 0x03, 0x31,
0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
0x02, 0x01, 0x30, 0x45, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x07, 0x01, 0xa0, 0x38, 0x04, 0x36, 0x15, 0x24, 0x00, 0x01, 0x25,
0x01, 0xfe, 0xca, 0x36, 0x02, 0x05, 0xce, 0xfa, 0x18, 0x25, 0x03, 0x34,
0x12, 0x2c, 0x04, 0x13, 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x31,
0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2d, 0x32, 0x34, 0x24,
0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x00,
0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa,
0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a,
0xdd, 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02,
0x20, 0x53, 0x25, 0x03, 0x2c, 0x96, 0x50, 0xb6, 0x64, 0xf4, 0x18, 0xbf,
0x99, 0x47, 0xf8, 0x9d, 0xe6, 0xeb, 0x43, 0x94, 0xf1, 0xce, 0xb2, 0x61,
0x00, 0xe0, 0xf9, 0x89, 0xa8, 0x71, 0x82, 0x02, 0x0a, 0x02, 0x21, 0x00,
0xea, 0x0a, 0x40, 0xab, 0x87, 0xad, 0x7e, 0x25, 0xe1, 0xa1, 0x6c, 0xb1,
0x12, 0xfa, 0x86, 0xfe, 0xea, 0x8a, 0xaf, 0x4b, 0xc1, 0xf3, 0x6f, 0x09,
0x85, 0x46, 0x50, 0xb6, 0xd0, 0x55, 0x40, 0xe2
};
建構目標
使用新建立的憑證建構並刷新目標。這個部分會因平台而異。詳情請參閱 SoC 說明文件或支援的裝置。
委任裝置
您現在可以按照「配對 Matter 裝置」一文中的步驟,在 Google Home platform 上啟用 Matter 裝置。
使用 chip-tool
偵錯
chip-tool
是檢查裝置是否傳送正確憑證的重要工具。如要建構此專案,請按照下列步驟操作:
$ cd examples/chip-tool
$ gn gen out/debug
Done. Made 114 targets from 112 files in 157ms
$ ninja -C out/debug
ninja: Entering directory `out/debug'
$ cd ../..
如要啟用其他記錄,請務必在執行 chip-tool
時傳遞 --trace_decode 1
旗標。此外,建議您使用 --paa-trust-store-path
旗標傳遞 PAA 檔案的路徑。
因此,如要使用 BLE 調試 Thread 裝置,可以執行以下指令:
```
$ examples/chip-tool/out/debug/chip-tool pairing ble-thread 1 \
hex:Thread_credentials \
pairing_code \
discriminator \
--paa-trust-store-path <path to PAA folder> \
--trace_decode 1
```
在測試裝置的情況下,<PAIRING CODE>
是 20202021
,<DISCRIMINATOR>
是 3840
。
如要從 Google Nest Hub (2nd gen) 取得 Thread 憑證,您可以執行以下命令:
$ adb connect border_router_ip_address
$ adb -e shell ot-ctl dataset active -x
$ adb disconnect
如要啟用 Wi-Fi 裝置,您可以使用 ble-wifi
選項:
$ examples/chip-tool/out/debug/chip-tool pairing ble-wifi 1 "SSID" SSID_password pairing_code discriminator