NCryptVerifyClaim 函式 (ncrypt.h)
驗證金鑰證明宣告。
語法
SECURITY_STATUS NCryptVerifyClaim(
[in] NCRYPT_KEY_HANDLE hSubjectKey,
[in, optional] NCRYPT_KEY_HANDLE hAuthorityKey,
[in] DWORD dwClaimType,
[in, optional] NCryptBufferDesc *pParameterList,
[in] PBYTE pbClaimBlob,
[in] DWORD cbClaimBlob,
[out] NCryptBufferDesc *pOutput,
[in] DWORD dwFlags
);
參數
[in] hSubjectKey
宣告的主旨索引鍵句柄。
[in, optional] hAuthorityKey
驗證宣告時要使用的授權單位金鑰句柄。 此參數是選擇性的,因為特定宣告類型的授權單位金鑰是獨立的。
[in] dwClaimType
宣告的類型。
[in, optional] pParameterList
選擇性參數清單。
[in] pbClaimBlob
輸入宣告 Blob。
[in] cbClaimBlob
pbClaimBlob 緩衝區的大小,以位元組為單位。
[out] pOutput
輸出 Blob。
[in] dwFlags
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG 是在驗證 VBS 產生的宣告期間設定的新旗標。 如需詳細資訊,請參閱 備註一節 一節。
目前沒有定義其他旗標。
dwFlags 參數應該設定為所有其他驗證類型的 0
。
傳回值
傳回狀態代碼,指出函式的成功或失敗。
以下是驗證 VBS 金鑰保護證明宣告時,可能會從驗證 API 傳回的一些錯誤碼:
傳回碼 | 意義 |
---|---|
NTE_BAD_TYPE | 宣告類型輸入參數與輸入宣告 Blob 的類型不同。 |
STATUS_BAD_DATA | 輸入宣告 Blob 無效。 |
STATUS_NO_MEMORY | 記憶體(宣告驗證所需的)配置失敗。 |
STATUS_INVALID_PARAMETER | 缺少強制輸入參數或其中一個參數具有不合法的值。 |
STATUS_FAIL_CHECK | 輸入 Blob 宣告的檢查失敗。 |
NTE_BAD_VER | 宣告 Blob 版本不符合驗證實作。 |
NTE_BAD_FLAGS | 不支援 dwFlags 中提供的旗標。 |
言論
使用虛擬化型安全性保護/證明私鑰 (VBS)
注意
VBS 旗標的相關信息與發行前版本產品有關,在發行發行前可能會大幅修改。 Microsoft未就此處提供的資訊提供任何明示或默示擔保。
此 API 可協助根據 VBS 金鑰保護啟用安全性金鑰的進階證明,這是使用 VBS 保護及證明私鑰的 Windows 模組。 安全性密鑰的證明會證明此金鑰與錨定密鑰的關聯,也就是證明金鑰。 這項功能可藉由限制使用內容密鑰,來增強不同實體之間的通訊安全性層級。
API 會定義新的旗標,以支持根據 VBS 金鑰保護中的證明密鑰建立和驗證證明宣告。
以下是針對 API 定義的 dwClaimType 類型
宣告類型 | 描述 |
---|---|
NCRYPT_CLAIM_VBS_ROOT | 此類型表示產生的宣告是由 VBS 根金鑰所產生。 |
NCRYPT_CLAIM_VBS_IDENTITY | 此類型表示產生的宣告是由 VBS身分識別/證明所產生。 這表示宣告是由使用證明旗標提升的 VBS 金鑰所產生 NCRYPT_ALLOW_KEY_ATTESTATION_FLAG(請參閱下方的詳細數據)。 |
以下是在驗證證明宣告時,pParameterList 緩衝區中設定的緩衝區類型:
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
在
NCryptBuff nCryptVerifyClaimNCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS erDescNCryptVerifyClaim 中,dwClaimType 設定為NCRYPT_CLAIM_VBS_ROOT 的新結構。 結構定義為: typedef struct _NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS { ULONG ulKeyFlags; ULONGLONG ullTrustletId; ULONG ulTrustletSecurityVersion; ULONG ulTrustletDebuggable; } NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS, *PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS;
結構包含下列專案:
- ulKeyFlags – 識別金鑰所設定 NCRYPT_VBS_KEY_FLAG_* 值的組合。
- ullTrustletId – 建立宣告之 VBS Trustlet 原則元數據中的硬式編碼標識符整數。
- ulTrustletSecurityVersion – 建立宣告之 VBS Trustlet 的安全性版本號碼。 此版本反映哪些安全性更新已套用至 trustlet,因此表示其安全性層級。
-
ulTrustletDebuggable – 指出建立宣告的 VBS Trustlet 是否可偵錯。
1
值表示 trustlet 可偵錯,且0
表示無法偵錯的 trustlet
如果未來需要進一步的信息專案,則會定義新的結構和對應的結構類型。
注意
這個輸出參數必須在不再參考之後釋放。
NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS
要設定為
NCryptBuffer 的新結構, NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS 類型為NCryptBufferDesc nCryptVerifyClaimdwClaimType 設為NCRYPT_CLAIM_VBS_IDENTITY 的輸出參數。 結構定義為: typedef struct _NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS { ULONG ulKeyFlags; LPCWSTR pszSignatureHashAlg; ULONG ulPaddingScheme; LPCWSTR pszPaddingHashAlg; ULONG ulPaddingSalt; } NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS, *PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS;
結構包含下列專案:
- ulKeyFlags – 識別金鑰所設定 NCRYPT_VBS_KEY_FLAG_* 值的組合。
- pszSignatureHashAlg - 宣告簽章哈希演算法 Unicode 字串的指標。
- ulPaddingScheme - 透過在 BCryptSignHash 中建立宣告所使用之簽署演算法的填補配置。
pszPaddingHashAlg - 透過在 BCryptSignHash中建立宣告所使用之宣告填補哈希演算法的 Unicode 字串指標。 - ulPaddingSalt - 透過在 BCryptSignHash 中建立宣告所使用之簽署演算法的填補鹽。
如果未來需要進一步的信息專案,則會定義新的結構和對應的結構類型。
注意
這個輸出參數必須在不再參考之後釋放。 發行此參數的範例程式代碼會在下列程式碼範例中提供 ,。
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
要 NCryptBuffer 參數中設定的新緩衝區類型,NCryptBufferDesc*pOutput 參數 NCryptVerifyClaim。 這個類型表示 NCryptBuffer 包含資料結構 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS。
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
要 NCryptBuffer 參數中設定的新緩衝區類型,NCryptBufferDesc*pOutput 參數 NCryptVerifyClaim。 這個類型表示 NCryptBuffer 包含資料結構 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS。
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG
這是在驗證 VBS 產生的宣告期間,dwFlags 輸入參數中設定的新旗標。 設定此旗標 NCryptVerifyClaim 會產生具有內部 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS 或 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS 參數緩衝區類型的 NCryptBufferDesc 輸出參數。
下表描述輸入和輸出資料結構類型在成功案例中具有 NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG的關聯性:
輸入 輸出 dwClaimType = NCRYPT_CLAIM_VBS_ROOT
具有內部 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS 信息結構的 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS 緩衝區類型。 dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY
具有內部 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS 信息結構的 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS 緩衝區類型。
例子
此範例說明現有 API 的使用方式,以驗證與 NCryptCreateClaim一起產生的證明宣告。
驗證 API 可以在本機叫用(在產生宣告 Blob 的電腦上)或遠端叫用。 驗證程式需要這些元素,對應至宣告產生金鑰:
- 宣告 Blob
- 公用證明金鑰 Blob
- 公用令牌 (一般用途) 金鑰 Blob
如果已設定輸入 NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG 旗標,驗證 API 會產生其中一個輸出信息結構,NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS 或 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS。 這些結構的記憶體會在程式碼流程結尾釋放,以避免記憶體流失。
HRESULT VerifyClaim(
BCRYPT_RSAKEY_BLOB *pAttestPublicKeyBlob,
BCRYPT_RSAKEY_BLOB *pTokenPublicKeyBlob,
PBYTE pRootClaim,
DWORD rootClaimSize,
PBYTE pIdentityClaim,
DWORD identityClaimSize)
{
HRESULT hr = S_OK;
DWORD bytesWritten = 0;
NCRYPT_PROV_HANDLE provider = NULL;
if (FAILED(hr = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0)))
{
wprintf(L"Error opening storage provider in NCryptOpenStorageProvider: 0x%X\n", hr);
goto cleanup;
}
NCRYPT_KEY_HANDLE attestPublicKey = NULL;
if (FAILED(hr = NCryptImportKey(
provider,
NULL,
BCRYPT_RSAPUBLIC_BLOB,
NULL,
&attestPublicKey,
(PBYTE)pAttestPublicKeyBlob,
GetRsaPublicKeyBlobSize(pAttestPublicKeyBlob),
0)))
{
wprintf(L"Unable to create a key handle for attestation public key blob with NCryptImportKey(): 0x%X\n", hr);
goto cleanup;
}
NCRYPT_KEY_HANDLE tokenPublicKey = NULL;
if (FAILED(hr = NCryptImportKey(
provider,
NULL,
BCRYPT_RSAPUBLIC_BLOB,
NULL,
&tokenPublicKey,
(PBYTE)pTokenPublicKeyBlob,
GetRsaPublicKeyBlobSize(pTokenPublicKeyBlob),
0)))
{
wprintf(L"Unable to create a key handle for token public key blob with NCryptImportKey(): 0x%X\n", hr);
goto cleanup;
}
NCryptBufferDesc rootOutput{};
// Verify the VBS root claim using the attestation/identity public key
if (FAILED(hr = NCryptVerifyClaim(
attestPublicKey,
NULL,
NCRYPT_CLAIM_VBS_ROOT, // Created claim by IDKS (VBS root signing key)
NULL, // parameters
pRootClaim,
rootClaimSize,
&rootOutput,
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG /*dwFlags*/)))
{
switch (hr)
{
case STATUS_OBJECT_TYPE_MISMATCH:
wprintf(L"The dwClaimType parameter’s value is different than the claim’s type.\n-----\n", hr);
break;
case STATUS_BAD_DATA:
wprintf(L"Something wrong in one of the data structures. E.g. Magic value mismatch\n-----\n", hr);
break;
case STATUS_NO_MEMORY:
wprintf(L"Memory allocation failed\n-----\n", hr);
break;
case STATUS_INVALID_PARAMETER:
wprintf(L"Missing mandatory parameter or one of the parameters has a bad value.\n-----\n", hr);
break;
case STATUS_FAIL_CHECK:
wprintf(L"One of the claim checks has failed.\n-----\n", hr);
break;
default:
wprintf(L"Unable to verify VBS root claim from NCryptVerifyClaim(): 0x%X\n-----\n", hr);
}
goto cleanup;
}
PNCryptBuffer pRootOutBuffer;
DWORD count;
// Look into the retrieved VBS root claim details
for (count = 0; count < rootOutput.cBuffers; ++count)
{
pRootOutBuffer = rootOutput.pBuffers[count];
if (pRootOutBuffer->BufferType == NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS)
{
PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS pDetails =
(PNCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS) pRootOutBuffer->pvBuffer;
wprintf(L"The claim trustlet id is: %lu\n-----\n", pDetails->ullTrustletId);
wprintf(L"The claim trustlet Security Version number is: %llu\n-----\n", pDetails->ulTrustletSecurityVersion);
}
}
NCryptBufferDesc identityOutput{};
// Verify the identity claim using the attestation/identity and token public keys
if (FAILED(hr = NCryptVerifyClaim(
tokenPublicKey,
attestPublicKey,
NCRYPT_CLAIM_VBS_IDENTITY, // Claim created by an attestation/identity key
NULL, // parameters
pIdentityClaim,
identityClaimSize,
&identityOutput,
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG /*dwFlags*/)))
{
wprintf(L"Unable to verify identity claim from NCryptVerifyClaim(): 0x%X\n-----\n", hr);
goto cleanup;
}
PNCryptBuffer pIdentityOutBuffer;
// Look into the retrieved identity claim details
for (count = 0; count < identityOutput.cBuffers; ++count)
{
pIdentityOutBuffer = identityOutput.pBuffers[count];
if (pIdentityOutBuffer->BufferType == NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS)
{
PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS pDetails =
(PNCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS) pIdentityOutBuffer->pvBuffer;
wprintf(L"The claim hash algorithm is: %S\n-----\n", pDetails-> pszSignatureHashAlg);
wprintf(L"The claim padding scheme is: %lu\n-----\n", pDetails->ulPaddingScheme);
}
}
wprintf(L"Verify claim for root and identity types passed successfully\n");
cleanup:
if (provider != NULL)
{
NCryptFreeObject(provider);
}
if (attestPublicKey != NULL)
{
CryptDestroyKey(attestPublicKey);
}
if (tokenPub != NULL)
{
CryptDestroyKey(tokenPublicKey);
}
if (rootOutput.pBuffers != NULL)
{
for (count = 0; count < rootOutput.cBuffers; ++count)
{
NCryptFreeBuffer(rootOutput.pBuffers[count].pvBuffer);
}
NCryptFreeBuffer(rootOutput.pBuffers);
}
if (identityOutput.pBuffers != NULL)
{
for (count = 0; count < identityOutput.cBuffers; ++count)
{
NCryptFreeBuffer(identityOutput.pBuffers[count].pvBuffer);
}
NCryptFreeBuffer(identityOutput.pBuffers);
}
return hr;
}
DWORD GetRsaPublicKeyBlobSize(BCRYPT_RSAKEY_BLOB* publicKeyBlob)
{
return sizeof(BCRYPT_RSAKEY_BLOB) +
publicKeyBlob->cbModulus +
publicKeyBlob->cbPublicExp;
}
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows 10 [傳統型應用程式 |UWP 應用程式] |
支援的最低伺服器 | Windows Server 2016 [傳統型應用程式 |UWP 應用程式] |
目標平臺 | 窗戶 |
標頭 | ncrypt.h |
連結庫 | Ncrypt.lib |
DLL | Ncrypt.dll |