Função NCryptVerifyClaim (ncrypt.h)
Verifica uma declaração de atestado de chave.
Sintaxe
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
);
Parâmetros
[in] hSubjectKey
O identificador de chave do assunto para a declaração.
[in, optional] hAuthorityKey
O identificador de chave de autoridade a ser usado ao verificar a declaração. Esse parâmetro é opcional porque a chave de autoridade é independente para determinados tipos de declaração.
[in] dwClaimType
O tipo de declaração.
[in, optional] pParameterList
Uma lista de parâmetros opcional.
[in] pbClaimBlob
O blob de declaração de entrada.
[in] cbClaimBlob
O tamanho, em bytes, do buffer de pbClaimBlob.
[out] pOutput
O blob de saída.
[in] dwFlags
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG é um novo sinalizador a ser definido durante a verificação de uma declaração gerada por VBS. Consulte a seção comentários
No momento, não há outros sinalizadores definidos. O parâmetro dwFlags
Valor de retorno
Retorna um código de status que indica o êxito ou a falha da função.
Veja a seguir alguns dos códigos de erro que podem ser retornados da API de verificação ao verificar declarações de atestado de proteção de chave VBS:
Código de retorno | Significado |
---|---|
NTE_BAD_TYPE | O parâmetro de entrada do tipo de declaração é diferente do tipo do blob de declaração de entrada. |
STATUS_BAD_DATA | O blob de declaração de entrada é inválido. |
STATUS_NO_MEMORY | Falha na alocação de memória (necessária para verificação de declaração). |
STATUS_INVALID_PARAMETER | Falta um parâmetro de entrada obrigatório ou um dos parâmetros tem um valor ilegal. |
STATUS_FAIL_CHECK | As verificações da declaração de blob de entrada falharam. |
NTE_BAD_VER | A versão do blob de declaração não corresponde à implementação de verificação. |
NTE_BAD_FLAGS | Não há suporte para os sinalizadores fornecidos em dwFlags. |
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 e 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 no buffer de pParameterList ao verificar uma declaração de atestado:
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
Uma nova estrutura a ser definida como um item de
NCryptBuffer do tipoNCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS no parâmetro de saída NCryptBufferDescNCryptVerifyClaim com dwClaimType definido comoNCRYPT_CLAIM_VBS_ROOT . A definição da estrutura é: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;
A estrutura inclui estes itens:
ulKeyFlags – uma combinação de valoresNCRYPT_VBS_KEY_FLAG_* que foram definidos para a chave de identidade. - ullTrustletId – um inteiro de identificador codificado em código nos metadados de política do VBS Trustlet que criou a declaração.
- ulTrustletSecurityVersion – o número de versão de segurança do VBS Trustlet que criou a declaração. Esta versão reflete quais atualizações de segurança foram aplicadas ao trustlet e, consequentemente, implica o nível de sua segurança.
-
ulTrustletDebuggable – uma indicação se o Trustlet VBS que criou a declaração for depurável. Um valor
1
indica que o trustlet é depurável e um0
indica um trustlet não depurável
Se mais itens informativos forem necessários no futuro, uma nova estrutura e um tipo de estrutura correspondente serão definidos.
Nota
Esse parâmetro de saída deve ser liberado depois de não ser mais referenciado.
NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS
Uma nova estrutura a ser definida como um
nCryptBuffer item do tipoNCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS no parâmetro de saída NCryptBufferDescNCryptVerifyClaim com dwClaimType definido como NCRYPT_CLAIM_VBS_IDENTITY . A definição da estrutura é: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;
A estrutura inclui estes itens:
ulKeyFlags – uma combinação de valoresNCRYPT_VBS_KEY_FLAG_* que foram definidos para a chave de identidade. - pszSignatureHashAlg – um ponteiro para uma cadeia de caracteres Unicode do algoritmo de hash de assinatura de declaração.
- ulPaddingScheme – Esquema de preenchimento do algoritmo de assinatura que foi usado por meio da criação de declarações em BCryptSignHash.
- pszPaddingHashAlg – um ponteiro para uma cadeia de caracteres Unicode do algoritmo de hash de preenchimento de declaração usado por meio da criação de declaração em BCryptSignHash.
- ulPaddingSalt – Sal de preenchimento do algoritmo de assinatura que foi usado por meio da criação de declarações em BCryptSignHash.
Se mais itens informativos forem necessários no futuro, uma nova estrutura e um tipo de estrutura correspondente serão definidos.
Nota
Esse parâmetro de saída deve ser liberado depois de não ser mais referenciado. O código de exemplo para liberar esse parâmetro é dado no exemplo de código abaixo.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
Um novo tipo de buffer a ser definido em um parâmetro NCryptBuffer no parâmetro NCryptBufferDesc*pOutput de NCryptVerifyClaim. Esse tipo indica que o NCryptBuffer
inclui a estrutura de dados NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS .NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
Um novo tipo de buffer a ser definido em um parâmetro NCryptBuffer no parâmetro NCryptBufferDesc*pOutput de NCryptVerifyClaim. Esse tipo indica que o NCryptBuffer
inclui a estrutura de dados NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS .NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG
Esse é um novo sinalizador a ser definido no parâmetro de entrada dwFlags durante a verificação de uma declaração gerada por VBS. Quando esse sinalizador é definido
NCryptVerifyClaim produz o parâmetro de saída NCryptBufferDesc com um tipo de buffer de parâmetro NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS ouNCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS interno.A tabela a seguir descreve a relação entre os tipos de estrutura de dados de entrada e saída, em um cenário bem-sucedido com NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG:
Entrada Saída dwClaimType = NCRYPT_CLAIM_VBS_ROOT
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS tipo de buffer com estrutura informativa NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS interna. dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS tipo de buffer com estrutura informativa NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS interna.
Exemplos
Este exemplo ilustra o uso da API existente para verificar as declarações de atestado que foram geradas com NCryptCreateClaim.
A API de verificação pode ser invocada localmente (no computador que gerou o blob de declaração) ou remotamente. O procedimento de verificação requer esses elementos, correspondentes às chaves de geração de declaração:
- Blob de declaração
- Blob de chave de atestado público
- Blob de chave de token público (uso geral)
A API de verificação produzirá uma das estruturas informativas de saída NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS ou NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS se o sinalizador de entrada NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG estiver definido. A memória dessas estruturas é liberada no final do fluxo de código para evitar vazamentos de memória.
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;
}
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 |