Função NCryptCreateClaim (ncrypt.h)
Cria uma declaração de atestado de chave.
Sintaxe
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
);
Parâmetros
[in] hSubjectKey
O identificador de chave de assunto para o qual a declaração é criada.
[in, optional] hAuthorityKey
O identificador de chave de autoridade no qual a declaração se baseia.
[in] dwClaimType
O tipo de declaração.
[in, optional] pParameterList
Uma lista de parâmetros opcional.
[out] pbClaimBlob
Saída do blob de declaração criado.
[in] cbClaimBlob
O tamanho, em bytes, do buffer de pbClaimBlob.
[out] pcbResult
A saída do blob de declaração criado.
[in] dwFlags
No momento, não há nenhum sinalizador definido. O parâmetro dwFlags
Valor de retorno
Retorna um código de status que indica o êxito ou a falha da função.
Observações
Protegendo/atestando chaves privadas usando a VBS (Virtualization Based Security)
Nota
Informações sobre sinalizadores VBS referem-se ao produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.
Essa API ajuda a habilitar um atestado avançado de chaves de segurança com base na proteção de chave VBS, um módulo do Windows para proteger/atestar chaves privadas usando VBS. O atestado de uma chave de segurança prova a associação dessa chave a uma chave ancorada, também conhecida como uma chave de atestado. Essa funcionalidade pode aprimorar o nível de segurança de comunicação entre diferentes entidades restringindo o uso de chaves fora de contexto.
A API define novos sinalizadores para dar suporte à criação e verificação de declarações de atestado com base em chaves de atestado na proteção de chave VBS.
Veja a seguir tipos de dwClaimType definidos para a API:
Tipo de declaração | Descrição |
---|---|
NCRYPT_CLAIM_VBS_ROOT | Esse tipo indica que a declaração gerada é produzida pela chave raiz do VBS. |
NCRYPT_CLAIM_VBS_IDENTITY | Esse tipo indica que a declaração gerada é produzida por uma identidade/atestado de VBS. Isso significa que a declaração é produzida por uma chave VBS que é elevada com o sinalizador de atestado NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (consulte os detalhes abaixo). |
Veja a seguir os tipos de buffer a serem definidos em buffer de pParameterList ao criar uma declaração de atestado:
Tipo de buffer | Descrição |
---|---|
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH | Um tipo de buffer a ser definido em um buffer de parâmetro ao criar uma declaração de atestado no NCryptCreateClaim. Esse é um tipo de parâmetro obrigatório para declarações NCRYPT_CLAIM_VBS_IDENTITY. Esse parâmetro configura o tipo de função de hash a ser usado por meio da criação da declaração de atestado. Os valores para esse parâmetro são definidos em ncrypt.h (como as constantes em identificadores de algoritmo 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 | Um tipo de buffer a ser definido em um buffer de parâmetro ao criar uma declaração de atestado no NCryptCreateClaim. Esse é um parâmetro obrigatório caso a chave de atestado na declaração de NCRYPT_CLAIM_VBS_IDENTITY criada seja uma chave RSA. Esse parâmetro configura o esquema de preenchimento para o tipo de função de assinatura a ser usado por meio da criação da declaração de atestado. Os valores opcionais para esse parâmetro são definidos em #define BCRYPT_PAD_PSS 0x00000008 |
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO | Um novo tipo de buffer a ser definido em um buffer de parâmetro ao criar uma declaração de atestado no NCryptCreateClaim. Esse é um parâmetro obrigatório caso a chave de atestado na declaração de NCRYPT_CLAIM_VBS_IDENTITY criada seja uma chave RSA. O parâmetro é um ponteiro para uma cadeia de caracteres Unicode terminada em nulo que identifica o algoritmo criptográfico a ser usado para criar o preenchimento. Esse algoritmo deve ser um algoritmo de hash. Os valores para esse parâmetro são definidos em ncrypt.h (como as constantes em identificadores de algoritmo 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 | Um novo tipo de buffer a ser definido em um buffer de parâmetro ao criar uma declaração de atestado no NCryptCreateClaim. Esse é um parâmetro obrigatório caso a chave de atestado na declaração de NCRYPT_CLAIM_VBS_IDENTITY criada seja uma chave RSA. O parâmetro representa um tamanho, em bytes, do sal aleatório a ser usado para o preenchimento. |
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE | Um tipo de buffer a ser definido em um buffer de parâmetro ao criar uma declaração de atestado em NCryptCreateClaim. Esse parâmetro é um alias para NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCE. |
Exemplos
Este exemplo ilustra o uso do novo sinalizador de API NCRYPT_ALLOW_KEY_ATTESTATION_FLAG. Além disso, o valor de nonce para a criação da declaração é definido pelo tipo de parâmetro NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE.
O exemplo consiste nestas etapas principais:
- Uma nova chave de atestado é criada. A chave é especializada usando a função de API NCryptSetProperty. A geração de um atestado baseia-se em uma chave de assinatura.
- Uma declaração é criada para atestado adicional. A declaração está associada à chave de atestado e a uma chave VBS interna. A declaração pode ser verificada em NCryptVerifyClaim fornecendo a chave de atestado.
- O objeto de chave de atestado é liberado para evitar perda de memória.
// 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;
}
Este próximo exemplo ilustra o uso de novos parâmetros de API para criar uma chave criptográfica de uso geral e uma declaração de atestado associada. Essa chave de uso geral é usada para gerar uma declaração de atestado.
O tipo de algoritmo de hash e o preenchimento para a criação da declaração são definidos nos parâmetros
Observe que:
- O parâmetro NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH é obrigatório apenas para declarações NCRYPT_CLAIM_VBS_IDENTITY e sem sentido em outros tipos de declarações.
- O parâmetro NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING é obrigatório apenas para declarações NCRYPT_CLAIM_VBS_IDENTITY no caso de uma chave de atestado RSA. Em outros tipos de declarações, não tem sentido.
A declaração nos permite verificar se a chave de uso geral está associada à chave de atestado.
//
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;
Requisitos
Requisito | Valor |
---|---|
de cliente com suporte mínimo | Windows 10 [aplicativos da área de trabalho | Aplicativos UWP] |
servidor com suporte mínimo | Windows Server 2016 [aplicativos da área de trabalho | Aplicativos UWP] |
da Plataforma de Destino |
Windows |
cabeçalho | ncrypt.h |
biblioteca | Ncrypt.lib |
de DLL |
Ncrypt.dll |