Функция NCryptCreateClaim (ncrypt.h)
Создает утверждение аттестации ключей.
Синтаксис
SECURITY_STATUS NCryptCreateClaim(
[in] NCRYPT_KEY_HANDLE hSubjectKey,
[in, optional] NCRYPT_KEY_HANDLE hAuthorityKey,
[in] DWORD dwClaimType,
[in, optional] NCryptBufferDesc *pParameterList,
[out] PBYTE pbClaimBlob,
[in] DWORD cbClaimBlob,
[out] DWORD *pcbResult,
[in] DWORD dwFlags
);
Параметры
[in] hSubjectKey
Дескриптор ключа субъекта, для которому создается утверждение.
[in, optional] hAuthorityKey
Ключ центра обрабатывает утверждение на основе утверждения.
[in] dwClaimType
Тип утверждения.
[in, optional] pParameterList
Необязательный список параметров.
[out] pbClaimBlob
Выходные данные созданного большого двоичного объекта утверждения.
[in] cbClaimBlob
Размер в байтах буфера pbClaimBlob.
[out] pcbResult
Выходные данные созданного большого двоичного объекта утверждения.
[in] dwFlags
В настоящее время нет определенных флагов. Параметр 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 при создании утверждения аттестации:
Тип буфера | Описание |
---|---|
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH | Тип буфера, который необходимо задать в буфере параметров при создании утверждения аттестации в NCryptCreateClaim. Это обязательный тип параметра для утверждений NCRYPT_CLAIM_VBS_IDENTITY. Этот параметр настраивает тип хэш-функции для использования с помощью создания утверждения аттестации. Значения этого параметра определяются в ncrypt.h (например, константы в идентификаторы алгоритма CNG):#define NCRYPT_SHA1_ALGORITHM BCRYPT_SHA1_ALGORITHM #define NCRYPT_SHA256_ALGORITHM BCRYPT_SHA256_ALGORITHM #define NCRYPT_SHA384_ALGORITHM BCRYPT_SHA384_ALGORITHM #define NCRYPT_SHA512_ALGORITHM BCRYPT_SHA512_ALGORITHM |
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_SCHEME | Тип буфера, который необходимо задать в буфере параметров при создании утверждения аттестации в NCryptCreateClaim. Это обязательный параметр, если ключ аттестации в созданном утверждении NCRYPT_CLAIM_VBS_IDENTITY является ключом RSA. Этот параметр настраивает схему заполнения для типа функции подписи для использования с помощью создания утверждения аттестации. Необязательные значения этого параметра определены в #define BCRYPT_PAD_PSS 0x00000008 |
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO | Новый тип буфера, который необходимо задать в буфере параметров при создании утверждения аттестации в NCryptCreateClaim. Это обязательный параметр, если ключ аттестации в созданном утверждении NCRYPT_CLAIM_VBS_IDENTITY является ключом RSA. Параметр — это указатель на строку Юникода, завершающую значение NULL, которая идентифицирует алгоритм шифрования, используемый для создания заполнения. Этот алгоритм должен быть хэш-алгоритмом. Значения этого параметра определяются в ncrypt.h (например, константы в идентификаторы алгоритма CNG):#define NCRYPT_SHA1_ALGORITHM BCRYPT_SHA1_ALGORITHM #define NCRYPT_SHA256_ALGORITHM BCRYPT_SHA256_ALGORITHM #define NCRYPT_SHA384_ALGORITHM BCRYPT_SHA384_ALGORITHM #define NCRYPT_SHA512_ALGORITHM BCRYPT_SHA512_ALGORITHM |
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_SALT_SIZE | Новый тип буфера, который необходимо задать в буфере параметров при создании утверждения аттестации в NCryptCreateClaim. Это обязательный параметр, если ключ аттестации в созданном утверждении NCRYPT_CLAIM_VBS_IDENTITY является ключом RSA. Параметр представляет размер в байтах случайной соли, используемой для заполнения. |
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE | Тип буфера, который необходимо задать в буфере параметров при создании утверждения аттестации в NCryptCreateClaim. Этот параметр является псевдонимом для NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCE. |
Примеры
В этом примере показано использование нового флага API NCRYPT_ALLOW_KEY_ATTESTATION_FLAG. Кроме того, значение nonce для создания утверждения задается типом параметра NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE.
Пример состоит из следующих основных шагов:
- Создается новый ключ аттестации. Ключ специализирован с помощью функции API NCryptSetProperty. Создание аттестации основано на ключе подписывания.
- Утверждение создается для дальнейшей аттестации. Утверждение связано с ключом аттестации и встроенным ключом VBS. Утверждение может быть проверено в NCryptVerifyClaim, предоставив ключ аттестации.
- Объект ключа аттестации освобождается, чтобы избежать утечки памяти.
// Create an attestation/identity key. This function is invoked in the main code flow below.
NCRYPT_KEY_HANDLE CreateAttestationKey(NCRYPT_PROV_HANDLE provider)
{
NCRYPT_KEY_HANDLE attestationKey = NULL;
HRESULT hr;
if (FAILED(hr = NCryptCreatePersistedKey(
provider,
&attestationKey,
BCRYPT_RSA_ALGORITHM,
L"AttestationKey", // a unique name for the attestation key in the key store
0, //dwLegacyKeySpec, not used
NCRYPT_REQUIRE_VBS_FLAG/*This flag targets VBS */)))
{
wprintf(L"Error creating an Attestation Identity Key with NCryptCreatePersistedKey(): 0x%X\n", hr);
goto cleanup;
}
// This is a new flag. It’s used to enable the capability in an attestation key.
DWORD keyUsagePolicy = NCRYPT_ALLOW_KEY_ATTESTATION_FLAG;
if (FAILED(hr = NCryptSetProperty(
attestationKey,
NCRYPT_KEY_USAGE_PROPERTY,
(PUCHAR)&keyUsagePolicy,
sizeof(keyUsagePolicy),
0 /*dwFlags*/)))
{
wprintf(L"Error setting property with NCryptSetProperty (): 0x%X\n", hr);
goto cleanup;
}
DWORD keySizeBits = 2048; // minimum allowed RSA key size
if (FAILED(hr = NCryptSetProperty(
attestationKey,
NCRYPT_LENGTH_PROPERTY,
(PUCHAR)&keySizeBits,
sizeof(keySizeBits),
0 /*dwFlags*/)))
{
wprintf(L"Error setting property with NCryptSetProperty (): 0x%X\n", hr);
goto cleanup;
}
if (FAILED(hr = NCryptFinalizeKey(attestationKey, 0 /*dwFlags*/)))
{
wprintf(L"Error finalizing key with NCryptFinalizeKey (): 0x%X\n", hr);
goto cleanup;
}
return attestationKey;
cleanup:
if (attestationKey != NULL)
{
NCryptFreeObject(attestationKey);
}
return NULL;
}
HRESULT CreateAttestation()
{
HRESULT hr = S_OK;
NCRYPT_PROV_HANDLE provider = NULL;
BYTE nonce[] = "TheSuperSecretNonce";
// This way of setting parameters is an existent pattern for NCrypt APIs
NCryptBuffer paramBuffers[] =
{
{ sizeof(nonce), NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE, (PBYTE)&nonce },
};
NCryptBufferDesc params = { NCRYPTBUFFER_VERSION, ARRAYSIZE(paramBuffers), paramBuffers };
if (FAILED(hr = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0)))
{
wprintf(L"Error opening storage provider in NCryptOpenStorageProvider: 0x%X\n", hr);
goto cleanup;
}
// Create a VBS attestation key
NCRYPT_KEY_HANDLE attestationKey = CreateAttestationKey(provider);
if (attestationKey == NULL)
{
hr = E_ABORT;
goto cleanup;
}
DWORD bytesWritten = 0;
if (FAILED(hr = NCryptCreateClaim(
attestationKey, // key that is being attested here and may attest other keys.
NULL, // implies that IDKS (VBS root signing key) will be used.
NCRYPT_CLAIM_VBS_ROOT, // used to attest a key with IDKS (VBS root signing key).
¶ms, // parameters list
NULL, // getting the size
0, // getting the size
&bytesWritten,
0 /*dwFlags*/)))
{
wprintf(L"Error creating claim with NCryptCreateClaim (): 0x%X\n", hr);
goto cleanup;
}
DWORD claimBufferSize = bytesWritten;
PBYTE claimBuffer = (PBYTE) HeapAlloc(GetProcessHeap(), 0,claimBufferSize);
if (NULL == claimBuffer)
{
hr = HRESULT_FROM_WIN32(GetLastError());
wprintf(L"Error allocating buffer for the claim: 0x%X\n", hr);
goto cleanup;
}
bytesWritten = 0;
if (FAILED(hr = NCryptCreateClaim(
attestationKey, // key that is being attested here and may attest other keys.
NULL, //implies that IDKS (VBS root signing key) will be used.
NCRYPT_CLAIM_VBS_ROOT, // used to attest with IDKS (VBS root signing key).
¶ms, // parameters list
claimBuffer,
claimBufferSize,
&bytesWritten,
0)))
{
wprintf(L"Error creating claim with NCryptCreateClaim (): 0x%X\n", hr);
goto cleanup;
}
wprintf(L"The claim is created successfully. It may be shared with the verifier side.\n");
cleanup:
if (provider != NULL)
{
NCryptFreeObject(provider);
}
if (attestationKey != NULL)
{
NCryptFreeObject(attestationKey);
}
if (claimBuffer)
{
HeapFree(GetProcessHeap(), 0, claimBuffer);
}
return hr;
}
В следующем примере показано использование новых параметров API для создания криптографического ключа общего назначения и связанного утверждения аттестации. Этот ключ общего назначения используется для создания утверждения аттестации.
Хэш-алгоритм и заполнение для создания утверждений задаются в параметрах NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH и NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_[SCHEME/ALGO/SALT_SIZE] соответственно.
Обратите внимание, что:
- Параметр NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH является обязательным только для NCRYPT_CLAIM_VBS_IDENTITY утверждений и без смысла в других типах утверждений.
- Параметр NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING является обязательным только для утверждений NCRYPT_CLAIM_VBS_IDENTITY в случае ключа аттестации RSA. В других типах утверждений это бессмысленно.
Утверждение позволяет проверить, связан ли ключ общего назначения с ключом аттестации.
//
HRESULT hr = S_OK;
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 attestationKey = NULL;
// Open the attestation key, created in CreateAttestationKey(), see previous example
if (FAILED(hr = NCryptOpenKey(
provider,
&attestationKey,
L"AttestationKey",
0, //dwLegacyKeySpec, not used
0 ,/* dwFlags */)))
{
wprintf(L"Error openning the attestation key with NCryptOpenKey (): 0x%X\n", hr);
goto cleanup;
}
NCRYPT_KEY_HANDLE tokenKey = NULL; // Token key that is bound to the security token
// Create VBS token (general purpose) key
if (FAILED(hr = NCryptCreatePersistedKey(
provider,
&tokenKey,
BCRYPT_RSA_ALGORITHM,
L"TokenKey",
0, //dwLegacyKeySpec, not used
NCRYPT_REQUIRE_VBS_FLAG /*This flag targets VBS*/)))
{
wprintf(L"Error creating an token key with NCryptCreatePersistedKey(): 0x%X\n", hr);
goto cleanup;
}
DWORD keySizeBits = 2048;
if (FAILED(hr = NCryptSetProperty(
tokenKey,
NCRYPT_LENGTH_PROPERTY,
(PUCHAR)&keySizeBits,
sizeof(keySizeBits),
0 /*dwFlags*/)))
{
wprintf(L"Error setting property with NCryptSetProperty (): 0x%X\n", hr);
goto cleanup;
}
if (FAILED(hr = NCryptFinalizeKey(tokenKey, 0 /*dwFlags*/)))
{
wprintf(L"Error finalizing key with NCryptFinalizeKey (): 0x%X\n", hr);
goto cleanup;
}
DWORD bytesWritten = 0;
DWORD hashAlgoType; // This is a new flag. It’s used to set type of hash algorithm of the claim// Set specific hash function type to produce the claim
wchar_t pHashAlgo[] = NCRYPT_SHA512_ALGORITHM;
// Set specific padding scheme for hash function to produce the claim
ULONG paddingScheme = BCRYPT_PAD_PSS;
wchar_t pPaddingAlgo[] = NCRYPT_SHA256_ALGORITHM;
ULONG paddingSalt = 345;
// This way of setting parameters is an existent pattern for NCrypt APIs
NCryptBuffer paramBuffers[] =
{
{ sizeof(NCRYPT_SHA512_ALGORITHM), NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH, (PBYTE)&pHashAlgo },
{ sizeof(paddingScheme), NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_SCHEME , (PBYTE)&paddingScheme },
{ sizeof(NCRYPT_SHA256_ALGORITHM), NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO, (PBYTE)&pPaddingAlgo },
{ sizeof(paddingSalt, NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_SALT_SIZE, (PBYTE)&paddingSalt }
};
NCryptBufferDesc params = { NCRYPTBUFFER_VERSION, ARRAYSIZE(paramBuffers), paramBuffers };
if (FAILED(hr = NCryptCreateClaim(
tokenKey, // key that is being attested
attestationKey,
NCRYPT_CLAIM_VBS_IDENTITY, // attest general-purpose key with an attestation (identity) key.
¶ms, // parameters list
NULL, // getting the size
0, // getting the size
&bytesWritten,
0 /*dwFlags*/)))
{
wprintf(L"Error creating claim with NCryptCreateClaim (): 0x%X\n", hr);
goto cleanup;
}
DWORD claimBufferSize = bytesWritten;
PBYTE claimBuffer = (PBYTE) HeapAlloc(GetProcessHeap(), 0,claimBufferSize);
if (NULL == claimBuffer)
{
hr = HRESULT_FROM_WIN32(GetLastError());
wprintf(L"Error allocating buffer for the claim: 0x%X\n", hr);
goto cleanup;
}
bytesWritten = 0;
if (FAILED(hr = NCryptCreateClaim(
tokenKey, // key that is being attested
attestationKey, // we assume that it is already initialized
NCRYPT_CLAIM_VBS_IDENTITY, // attest general-purpose key with an attestation (identity) key
¶ms,
claimBuffer,
claimBufferSize,
&bytesWritten,
0)))
{
wprintf(L"Error creating claim with NCryptCreateClaim (): 0x%X\n", hr);
goto cleanup;
}
wprintf(L"The claim is created successfully. It may be shared with the verifier side.\n");
cleanup:
if (provider != NULL)
{
NCryptFreeObject(provider);
}
if (tokenKey != NULL)
{
NCryptFreeObject(tokenKey);
}
if (attestationKey != NULL)
{
NCryptDeleteKey(attestationKey);
}
if (claimBuffer)
{
HeapFree(GetProcessHeap(), 0, claimBuffer);
}
return hr;
Требования
Требование | Ценность |
---|---|
минимальные поддерживаемые клиентские | Windows 10 [классические приложения | Приложения UWP] |
минимальный поддерживаемый сервер | Windows Server 2016 [классические приложения | Приложения UWP] |
целевая платформа | Виндоус |
заголовка | ncrypt.h |
библиотеки |
Ncrypt.lib |
DLL | Ncrypt.dll |