Compartir a través de


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 un 0 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