什麼是機密 VM 的客體證明?
客體證明可協助您確認機密 VM 環境是否受到正版硬體支援的受信任執行環境 (TEE) 保護,且安全性功能已啟用來達到隔離和資料完整性。
您可以使用客體證明:
- 請確定機密 VM 在預期的硬體平台上執行
- 檢查機密 VM 是否已啟用安全開機。 此設定可保護 VM (韌體、開機載入器、核心) 的較低層級避免惡意程式碼 (Rootkit、Bootkit)。
- 取得機密 VM 在機密硬體上執行的信賴憑證者辨識項
注意
若要針對 Intel TDX 支援的 DCesv5 和 ECesv5 VM 執行客體證明,可在這裡取得操作指南。 使用 Intel 信任授權單位需要向 Intel 註冊。
案例
客體證明所涉及的主要元件和服務包括:
- 工作負載
- 客體證明程式庫
- 硬體 (用於報告)。 例如,AMD-SEVSNP。
- Microsoft Azure 證明服務
- JSON Web 權杖回應
典型的作業情節會納入用戶端程式庫,以提出證明要求,如下所示。
情節:在不同的工作負載中要求
在此範例情節中,會在個別的工作負載中提出證明要求。 要求會判斷機密 VM 在啟動工作負載之前,是否在正確的硬體平台上執行。
圖表中的工作負載 (平台檢查程式用戶端) 必須與證明程式庫整合,並在機密 VM 內執行,才能執行證明。 在程式向證明程式庫提出要求之後,工作負載會剖析回應,以判斷 VM 是否在正確的硬體平台和/或安全開機設定上執行,然後再啟動敏感性工作負載。
這個情節類似於下列情節。 主要差異在於每個情節如何根據要求的位置達成相同的目標。
情節:從工作負載內部要求
在此範例情節中,證明要求是在程式開頭的工作負載內提出。 要求會檢查機密 VM 在啟動工作負載之前,是否在正確的硬體平台上執行。
這個情節類似於先前的情節。 主要差異在於每個情節如何根據要求的位置達成相同的目標。
客戶工作負載必須與證明程式庫整合,並在機密 VM 內執行。 在客戶工作負載向證明程式庫提出要求之後,客戶工作負載會剖析回應,以判斷 VM 是否在正確的硬體平台和/或安全開機設定上執行,然後完全設定敏感性工作負載。
情節:信賴憑證者交握
在此範例情節中,機密 VM 必須證明它在機密平台上執行,信賴憑證者才會進行業務開發。 機密 VM 向信賴憑證者呈現證明權杖,以開始業務開發。
業務開發的一些範例如下:
- 機密 VM 需要來自祕密管理服務的祕密。
- 用戶端想要確保機密 VM 在機密平台上執行,再向機密 VM 顯示個人資料進行處理。
下圖顯示機密 VM 與信賴憑證者之間的交握。
下列循序圖進一步說明信賴憑證者情節。 相關系統之間的要求/回應會使用客體證明程式庫 API。 機密 VM 會與祕密管理員互動,以使用收到的祕密自行啟動程式。
API
Microsoft 提供客體證明程式庫與 API 來執行證明,以及加密和解密資料。 另外還有一個 API 可回收記憶體。
您可以針對先前所述的不同情節使用這些 API。
證明 API
證明API 會接受 ClientParameters
物件做為輸入,並傳回解密的證明權杖。 例如:
AttestationResult Attest([in] ClientParameters client_params,
[out] buffer jwt_token);
參數 | 資訊 |
---|---|
ClientParameters (類型:物件) |
接受版本 (類型的物件:uint32_t )、證明租用戶 URI (類型:不帶正負號字元),以及用戶端承載 (類型:不帶正負號的字元)。 針對回應承載中傳回的任何用戶端或客戶中繼資料,用戶端承載為零或多個機碼值組。 機碼值組必須是 JSON 字串格式 "{\"key1\":\"value1\",\"key2\":\"value2\"}" 。 例如,證明有效索引鍵值看起來可能像 {\”Nonce\”:\”011510062022\”} 。 |
buffer |
包含證明資訊的 JSON Web 權杖。 |
證明API 會傳回 AttestationResult
(類型:結構)。
加密 API
加密API 會採用要加密的資料,並將 JSON Web 權杖做為輸入。 API 會使用 JSON Web 權杖中存在的公用暫時金鑰來加密資料。 例如:
AttestationResult Encrypt(
[enum] encryption_type,
[in] const unsigned char* jwt_token,
[in] const unsigned char* data,
[in] uint32_t data_size,
[out] unsigned char** encrypted_data,
[out] uint32_t* encrypted_data_size,
[out] unsigned char** encryption_metadata,
[out] uint32_t encryption_metadata_size);
參數 | 說明 |
---|---|
encryption_type |
無。 |
const unsigned char* jwt_token |
包含證明資訊的 JSON Web 權杖。 |
const unsigned char* data |
要加密的資料 |
uint32_t data_size |
要加密的資料大小。 |
unsigned char** encrypted_data |
加密的資料。 |
uint32_t* encrypted_data_size |
加密資料的大小。 |
unsigned char** encryption_metadata |
加密中繼資料。 |
uint32_t encryption_metadata_size |
加密中繼資料的大小。 |
加密API 會傳回 AttestationResult
(類型:結構)。
解密 API
解密API 會採用加密的資料做為輸入,並使用密封至信賴平台模組的私人暫時金鑰來解密資料 (TPM)。 例如:
AttestationResult Decrypt([enum] encryption_type,
[in] const unsigned char* encrypted_data,
[in] uint32_t encrypted_data_size,
[in] const unsigned char* encryption_metadata,
[in] unit32_t encryption_metadata_size,
[out] unsigned char** decrypted_data,
[out] unit32_t decrypted_data_size);
參數 | 說明 |
---|---|
encryption_type |
無。 |
const unsigned char* encrypted_data |
要解密的資料。 |
uint32_t encrypted_data_size |
要解密的資料大小。 |
const unsigned char* encryption_metadata |
加密中繼資料。 |
unit32_t encryption_metadata_size |
加密中繼資料的大小。 |
unsigned char** decrypted_data |
解密的資料。 |
unit32_t decrypted_data_size |
解密資料的大小。 |
解密API 會傳回 AttestationResult
(類型:結構)。
免費 API
免費API 會回收資料所持有的記憶體。 例如:
Free([in] buffer data);
參數 | 說明 |
---|---|
data |
回收資料所持有的記憶體。 |
免費 API 不會傳回任何項目。
錯誤碼
API 可以傳回下列錯誤碼:
錯誤碼 | 描述 |
---|---|
1 | 初始化失敗時發生錯誤。 |
2 | 剖析回應時發生錯誤。 |
3 | 找不到 Azure 資源權杖的受控識別。 |
4 | 要求超過重試次數。 |
5 | 要求失敗。 |
6 | 證明失敗 |
7 | 傳送要求失敗。 |
8 | 無效的輸入參數。 |
9 | 證明參數驗證失敗。 |
10 | 記憶體配置失敗。 |
11 | 無法取得作業系統 (作業系統) 資訊。 |
12 | TPM 內部失敗 |
13 | TPM 作業失敗 |
14 | JSON Web 權杖解密失敗。 |
15 | JSON Web 權杖解密 TPM 錯誤。 |
16 | 不正確 JSON 回應。 |
17 | 空版本的晶片簽署金鑰 (VCEK) 憑證。 |
18 | 空白回應。 |
19 | 空白要求本文。 |
20 | 報告剖析失敗。 |
21 | 報告空白。 |
22 | 擷取 JSON Web 權杖資訊時發生錯誤。 |
23 | 將 JSON Web 權杖轉換為 RSA 公開金鑰時發生錯誤。 |
24 | EVP_PKEY 加密初始化失敗。 |
25 | EVP_PKEY 加密失敗。 |
26 | 資料解密 TPM 錯誤。 |
27 | 剖析 DNS 資訊時發生錯誤。 |
JSON Web 權杖
針對先前所述的不同 API 情節,您可以擷取 JSON Web 權杖的不同部分。 以下是客體證明功能的重要欄位:
索賠 | 屬性 | 範例值 |
---|---|---|
- | x-ms-azurevm-vmid |
2DEDC52A-6832-46CE-9910-E8C9980BF5A7 |
AMD SEV-SNP 硬體 | x-ms-isolation-tee |
sevsnpvm |
AMD SEV-SNP 硬體 | x-ms-compliance-status (在 x-ms-isolation-tee 之下) |
azure-compliant-cvm |
安全開機 | secure-boot (在 x-ms-runtime >vm-configuration 之下) |
true |
虛擬 TPM | tpm-enabled (在 x-ms-runtime >vm-configuration 之下) |
true |
虛擬 TPM | kid (在 x-ms-runtime >keys 之下) |
TpmEphemeralEncryptionKey |
{
"exp": 1653021894,
"iat": 1652993094,
"iss": "https://sharedeus.eus.test.attest.azure.net",
"jti": "<value>",
"nbf": 1652993094,
"secureboot": true,
"x-ms-attestation-type": "azurevm",
"x-ms-azurevm-attestation-protocol-ver": "2.0",
"x-ms-azurevm-attested-pcrs": [
0,
1,
2,
3,
4,
5,
6,
7,
11,
12,
13
],
"x-ms-azurevm-bootdebug-enabled": false,
"x-ms-azurevm-dbvalidated": true,
"x-ms-azurevm-dbxvalidated": true,
"x-ms-azurevm-debuggersdisabled": true,
"x-ms-azurevm-default-securebootkeysvalidated": true,
"x-ms-azurevm-elam-enabled": true,
"x-ms-azurevm-flightsigning-enabled": false,
"x-ms-azurevm-hvci-policy": 0,
"x-ms-azurevm-hypervisordebug-enabled": false,
"x-ms-azurevm-is-windows": true,
"x-ms-azurevm-kerneldebug-enabled": false,
"x-ms-azurevm-osbuild": "NotApplicable",
"x-ms-azurevm-osdistro": "Microsoft",
"x-ms-azurevm-ostype": "Windows",
"x-ms-azurevm-osversion-major": 10,
"x-ms-azurevm-osversion-minor": 0,
"x-ms-azurevm-signingdisabled": true,
"x-ms-azurevm-testsigning-enabled": false,
"x-ms-azurevm-vmid": "<value>",
"x-ms-isolation-tee": {
"x-ms-attestation-type": "sevsnpvm",
"x-ms-compliance-status": "azure-compliant-cvm",
"x-ms-runtime": {
"keys": [
{
"e": "AQAB",
"key_ops": [
"encrypt"
],
"kid": "HCLAkPub",
"kty": "RSA",
"n": "<value>"
}
],
"vm-configuration": {
"console-enabled": true,
"current-time": 1652993091,
"secure-boot": true,
"tpm-enabled": true,
"vmUniqueId": "<value>"
}
},
"x-ms-sevsnpvm-authorkeydigest": "<value>",
"x-ms-sevsnpvm-bootloader-svn": 2,
"x-ms-sevsnpvm-familyId": "<value>",
"x-ms-sevsnpvm-guestsvn": 1,
"x-ms-sevsnpvm-hostdata": "<value>",
"x-ms-sevsnpvm-idkeydigest": "<value>",
"x-ms-sevsnpvm-imageId": "<value>",
"x-ms-sevsnpvm-is-debuggable": false,
"x-ms-sevsnpvm-launchmeasurement": "<value>",
"x-ms-sevsnpvm-microcode-svn": 55,
"x-ms-sevsnpvm-migration-allowed": false,
"x-ms-sevsnpvm-reportdata": "<value>",
"x-ms-sevsnpvm-reportid": "<value>",
"x-ms-sevsnpvm-smt-allowed": true,
"x-ms-sevsnpvm-snpfw-svn": 2,
"x-ms-sevsnpvm-tee-svn": 0,
"x-ms-sevsnpvm-vmpl": 0
},
"x-ms-policy-hash": "<value>",
"x-ms-runtime": {
"keys": [
{
"e": "AQAB",
"key_ops": [
"encrypt"
],
"kid": "TpmEphemeralEncryptionKey",
"kty": "RSA",
"n": "<value>"
}
]
},
"x-ms-ver": "1.0"
}