Función NCryptVerifyClaim (ncrypt.h)
Comprueba una notificación de atestación de clave.
Sintaxis
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
Identificador de clave de asunto de la notificación.
[in, optional] hAuthorityKey
Identificador de clave de autoridad que se va a usar al comprobar la notificación. Este parámetro es opcional porque la clave de autoridad es independiente para determinados tipos de notificación.
[in] dwClaimType
Tipo de notificación.
[in, optional] pParameterList
Una lista de parámetros opcional.
[in] pbClaimBlob
Blob de notificación de entrada.
[in] cbClaimBlob
Tamaño, en bytes, del búfer de pbClaimBlob.
[out] pOutput
Blob de salida.
[in] dwFlags
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG es una nueva marca que se va a establecer durante la comprobación de una notificación generada por VBS. Consulte la sección comentarios para obtener más información.
Actualmente no hay otras marcas definidas. El parámetro dwFlags debe establecerse en 0
para todos los demás tipos de comprobación.
Valor devuelto
Devuelve un código de estado que indica el éxito o error de la función.
A continuación se muestran algunos de los códigos de error que se pueden devolver desde la API de comprobación al comprobar las notificaciones de atestación de protección de claves de VBS:
Código devuelto | Significado |
---|---|
NTE_BAD_TYPE | El parámetro de entrada del tipo de notificación es diferente del tipo del blob de notificación de entrada. |
STATUS_BAD_DATA | El blob de notificación de entrada no es válido. |
STATUS_NO_MEMORY | Error de asignación de memoria (necesaria para la comprobación de notificaciones). |
STATUS_INVALID_PARAMETER | Falta un parámetro de entrada obligatorio o uno de los parámetros tiene un valor no válido. |
STATUS_FAIL_CHECK | Se han producido errores en las comprobaciones de la notificación de blob de entrada. |
NTE_BAD_VER | La versión del blob de notificación no coincide con la implementación de comprobación. |
NTE_BAD_FLAGS | No se admiten las marcas proporcionadas en dwFlags. |
Observaciones
Protección o atestación de claves privadas mediante la seguridad basada en virtualización (VBS)
Nota
La información relacionada con las marcas vbS está relacionada con el producto de versión preliminar que puede modificarse sustancialmente antes de su publicación comercial. Microsoft no ofrece ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Esta API ayuda a habilitar una atestación avanzada de claves de seguridad basadas en la protección de claves VBS, un módulo de Windows para proteger y atestiguar claves privadas mediante VBS. La atestación de una clave de seguridad demuestra la asociación de esta clave a una clave anclada, también conocida como clave de atestación. Esta funcionalidad puede mejorar el nivel de seguridad de la comunicación entre diferentes entidades al restringir el uso de claves fuera del contexto.
La API define nuevas marcas para admitir la creación y comprobación de notificaciones de atestación basadas en claves de atestación en la protección de claves de VBS.
A continuación se muestran dwClaimType tipos definidos para la API:
Tipo de notificación | Descripción |
---|---|
NCRYPT_CLAIM_VBS_ROOT | Este tipo indica que la notificación generada se genera mediante la clave raíz de VBS. |
NCRYPT_CLAIM_VBS_IDENTITY | Este tipo indica que la notificación generada se genera mediante una identidad o atestación de VBS. Esto significa que la notificación se genera mediante una clave VBS con privilegios elevados con la marca de atestación NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (consulte los detalles a continuación). |
A continuación se muestran los tipos de búfer que se establecerán en pParameterList búfer al comprobar una notificación de atestación:
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
Nueva estructura que se va a establecer como un NCryptBuffer elemento de tipo NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS en NCryptBufferDesc parámetro de salida de NCryptVerifyClaim con dwClaimType establecido en NCRYPT_CLAIM_VBS_ROOT. La definición de la estructura es:
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;
La estructura incluye estos elementos:
- ulKeyFlags: una combinación de NCRYPT_VBS_KEY_FLAG_* valores establecidos para la clave de identidad.
- ullTrustletId: un entero de identificador codificado de forma rígida en los metadatos de directiva del Trustlet de VBS que creó la notificación.
- ulTrustletSecurityVersion: el número de versión de seguridad del trustlet de VBS que creó la notificación. Esta versión refleja qué actualizaciones de seguridad se han aplicado al trustlet y, por tanto, implica el nivel de su seguridad.
-
ulTrustletDebuggable: indicación de si se puede depurar el trustlet de VBS que creó la notificación. Un valor de
1
indica que el trustlet es depurable y un0
indica un trustlet no depurable.
Si se requieren elementos informativos adicionales en el futuro, se definirá una nueva estructura y un tipo de estructura correspondiente.
Nota
Este parámetro de salida debe liberarse después de que ya no se haga referencia a él.
NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS
Nueva estructura que se va a establecer como un NCryptBuffer elemento de tipo NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS en NCryptBufferDesc parámetro de salida de NCryptVerifyClaim con dwClaimType establecido en NCRYPT_CLAIM_VBS_IDENTITY. La definición de la estructura es:
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;
La estructura incluye estos elementos:
- ulKeyFlags: una combinación de NCRYPT_VBS_KEY_FLAG_* valores establecidos para la clave de identidad.
- pszSignatureHashAlg: puntero a una cadena Unicode del algoritmo hash de firma de notificación.
- ulPaddingScheme: esquema de relleno del algoritmo de firma que se usó a través de la creación de notificaciones en BCryptSignHash.
- pszPaddingHashAlg: puntero a una cadena Unicode del algoritmo hash de relleno de notificaciones usado a través de la creación de notificaciones en BCryptSignHash.
- ulPaddingSalt: sal de relleno del algoritmo de firma que se usó a través de la creación de notificaciones en BCryptSignHash.
Si se requieren elementos informativos adicionales en el futuro, se definirá una nueva estructura y un tipo de estructura correspondiente.
Nota
Este parámetro de salida debe liberarse después de que ya no se haga referencia a él. El código de ejemplo para liberar este parámetro se da en el ejemplo de código siguiente.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
Nuevo tipo de búfer que se va a establecer en un parámetro NCryptBuffer del NCryptBufferDesc*pOutput parámetro de NCryptVerifyClaim. Este tipo indica que el NCryptBuffer incluye la estructura de datos NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
Nuevo tipo de búfer que se va a establecer en un parámetro NCryptBuffer del NCryptBufferDesc*pOutput parámetro de NCryptVerifyClaim. Este tipo indica que el NCryptBuffer incluye la estructura de datos NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS.
NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG
Se trata de una nueva marca que se va a establecer en el dwFlags parámetro de entrada durante la comprobación de una notificación generada por VBS. Cuando se establece esta marca NCryptVerifyClaim genera el NCryptBufferDesc parámetro de salida con un tipo de búfer de parámetros NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS o NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS interno.
En la tabla siguiente se describe la relación entre los tipos de estructura de datos de entrada y salida, en un escenario correcto con NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG:
Entrada Salida dwClaimType = NCRYPT_CLAIM_VBS_ROOT
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS tipo de búfer con estructura NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS informativa interna. dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS tipo de búfer con NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS estructura informativa interna.
Ejemplos
En este ejemplo se muestra el uso de la API existente para comprobar las notificaciones de atestación que se generaron en con NCryptCreateClaim.
La API de comprobación se puede invocar localmente (en la máquina que generó el blob de notificaciones) o de forma remota. El procedimiento de comprobación requiere estos elementos, correspondientes a las claves de generación de notificaciones:
- Notificación de blob
- Blob de clave de atestación pública
- Blob de clave de token público (uso general)
La API de comprobación genera una de las estructuras informativas de salida NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS o NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS si se establece la marca de entrada NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG. La memoria de estas estructuras se libera al final del flujo de código para evitar pérdidas de memoria.
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 |
---|---|
cliente mínimo admitido | Windows 10 [aplicaciones de escritorio | Aplicaciones para UWP] |
servidor mínimo admitido | Windows Server 2016 [aplicaciones de escritorio | Aplicaciones para UWP] |
de la plataforma de destino de |
Windows |
encabezado de |
ncrypt.h |
biblioteca de |
Ncrypt.lib |
DLL de |
Ncrypt.dll |