Функция 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
Выходной большой двоичный объект.
[in] dwFlags
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG — это новый флаг, который необходимо задать во время проверки утверждения, созданного VBS. Дополнительные сведения см. в разделе примечаниях.
В настоящее время нет других флагов. Параметр dwFlags
Возвращаемое значение
Возвращает код состояния, указывающий на успешность или сбой функции.
Ниже приведены некоторые коды ошибок, которые могут быть возвращены из API проверки при проверке утверждений аттестации защиты ключей VBS:
Код возврата | Значение |
---|---|
NTE_BAD_TYPE | Входной параметр типа утверждения отличается от типа входного большого двоичного объекта утверждения. |
STATUS_BAD_DATA | Недопустимый blob-объект входного утверждения. |
STATUS_NO_MEMORY | Сбой выделения памяти (необходимой для проверки утверждений). |
STATUS_INVALID_PARAMETER | Отсутствует обязательный входной параметр или один из параметров имеет недопустимое значение. |
STATUS_FAIL_CHECK | Сбой проверок входного утверждения БОЛЬШОго двоичного объекта. |
NTE_BAD_VER | Версия большого двоичного объекта утверждения не соответствует реализации проверки. |
NTE_BAD_FLAGS | Флаги, предоставляемые в dwFlags, не поддерживаются. |
Замечания
Защита и подтверждение закрытых ключей с помощью безопасности на основе виртуализации (VBS)
Заметка
Сведения о флагах VBS относятся к предварительному выпуску продукта, который может быть существенно изменен до выпуска. Корпорация Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых в отношении информации, предоставленной здесь.
Этот API помогает включить расширенную аттестацию ключей безопасности на основе защиты ключей VBS, модуля Windows для защиты и проверки закрытых ключей с помощью VBS. Аттестация ключа безопасности подтверждает связь этого ключа с привязанным ключом и ключом аттестации. Эта возможность может повысить уровень безопасности взаимодействия между различными сущностями, ограничив использование ключей вне контекста.
API определяет новые флаги для поддержки создания и проверки утверждений аттестации на основе ключей аттестации в защите ключей VBS.
Ниже приведены типы dwClaimType, определенные для API:
Тип утверждения | Описание |
---|---|
NCRYPT_CLAIM_VBS_ROOT | Этот тип указывает, что созданное утверждение создается корневым ключом VBS. |
NCRYPT_CLAIM_VBS_IDENTITY | Этот тип указывает, что созданное утверждение создается удостоверением или аттестацией VBS. Это означает, что утверждение создается ключом VBS, который повышен с помощью флага аттестации NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (см. подробные сведения ниже). |
Ниже приведены типы буферов, которые необходимо задать в буфере pParameterList при проверке утверждения аттестации:
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
Новая структура, которая должна быть задана как элемент NCryptBuffer типа NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS в NCryptBufferDesc выходного параметра NCryptVerifyClaim с 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 — целое число жестко закодированного идентификатора в метаданных политики ВBS Trustlet, создавшего утверждение.
- ulTrustletSecurityVersion — номер версии безопасности доверенного объекта VBS, создавшего утверждение. Эта версия отражает, какие обновления безопасности были применены к доверенному объекту и, следовательно, подразумевает уровень его безопасности.
-
ulTrustletDebuggable — указывает, является ли отлаживаемый объект VBS Trustlet, созданный утверждением. Значение
1
указывает, что отладчик доверия является отлаживаемым, а0
указывает на не отладчик доверия.
Если в будущем требуются дополнительные информативные элементы, будет определена новая структура и соответствующий тип структуры.
Заметка
Этот выходной параметр должен быть выпущен после того, как он больше не ссылается.
NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS
Новая структура, которая должна быть задана как элемент NCryptBuffer типа NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILSв параметре NCryptBufferDesc выходного параметра NCryptVerifyClaim с dwClaimType для 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 — указатель на строку Юникода хэш-алгоритма сигнатуры утверждения.
- ulPaddingScheme — схема подписывания алгоритма подписывания, который использовался путем создания утверждений в BCryptSignHash.
- pszPaddingHashAlg — указатель на строку Юникода хэш-алгоритма утверждения, используемого с помощью создания утверждений в BCryptSignHash.
- ulPaddingSalt — заполнение соли алгоритма подписи, который использовался с помощью создания утверждений в BCryptSignHash.
Если в будущем требуются дополнительные информативные элементы, будет определена новая структура и соответствующий тип структуры.
Заметка
Этот выходной параметр должен быть выпущен после того, как он больше не ссылается. Пример кода для освобождения этого параметра приведен в примере кода ниже.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
Новый тип буфера, который необходимо задать в параметре NCryptBufferв параметре NCryptBufferDesc*pOutputNCryptVerifyClaim. Этот тип указывает, что NCryptBuffer включает структуру данных NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
Новый тип буфера, который необходимо задать в параметре NCryptBufferв параметре NCryptBufferDesc*pOutputNCryptVerifyClaim. Этот тип указывает, что NCryptBuffer включает структуру данных NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS.
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG
Это новый флаг, который необходимо задать в dwFlags входной параметр во время проверки создаваемого утверждения VBS. Если этот флаг задан NCryptVerifyClaim создает параметр вывода NCryptBufferDesc с внутренним NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS или типом буфера параметров NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS.
В следующей таблице описывается отношение между типами структуры входных и выходных данных в успешном сценарии с NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG:
Ввод Выпуск dwClaimType = NCRYPT_CLAIM_VBS_ROOT
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS тип буфера с внутренней информативной структурой NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS. dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS тип буфера с внутренней NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS информационной структурой.
Примеры
В этом примере показано использование существующего API для проверки утверждений аттестации, созданных с помощью NCryptCreateClaim.
API проверки может вызываться локально (на компьютере, который создал большой двоичный объект утверждения) или удаленно. Для процедуры проверки требуются следующие элементы, соответствующие ключам создания утверждений:
- Утверждение большого двоичного объекта
- Общедоступный ключ аттестации blob-объект
- Большой двоичный объект открытого токена (общего назначения)
API проверки создает одну из выходных информационных структур NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS или NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS, если установлен флаг ввода NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG. Память этих структур освобождается в конце потока кода, чтобы избежать утечки памяти.
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 |