Partager via


NCryptCreateClaim, fonction (ncrypt.h)

Crée une revendication d’attestation de clé.

Syntaxe

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
);

Paramètres

[in] hSubjectKey

Handle de clé d’objet pour lequel la revendication est créée.

[in, optional] hAuthorityKey

La clé d’autorité gère la revendication sur laquelle repose la revendication.

[in] dwClaimType

Type de revendication.

[in, optional] pParameterList

Liste de paramètres facultative.

[out] pbClaimBlob

Sortie de l’objet blob de revendication créé.

[in] cbClaimBlob

Taille, en octets, de la mémoire tampon pbClaimBlob.

[out] pcbResult

Sortie de l’objet blob de revendication créé.

[in] dwFlags

Il n’existe actuellement aucun indicateur défini. Le paramètre dwFlags doit être défini sur 0.

Valeur de retour

Retourne un code d’état qui indique la réussite ou l’échec de la fonction.

Remarques

Protection/attestation de clés privées à l’aide de la sécurité basée sur la virtualisation (VBS)

Note

Les informations relatives aux indicateurs VBS concernent le produit de préversion susceptible d’être sensiblement modifié avant sa publication commerciale. Microsoft n’offre aucune garantie, expresse ou implicite, en ce qui concerne les informations fournies ici.

Cette API permet d’activer une attestation avancée des clés de sécurité basées sur la protection des clés VBS, un module Windows pour protéger/attester des clés privées à l’aide de VBS. L’attestation d’une clé de sécurité prouve l’association de cette clé à une clé ancrée, une clé d’attestation. Cette fonctionnalité peut améliorer le niveau de sécurité de la communication entre différentes entités en limitant l’utilisation des clés hors contexte.

L’API définit de nouveaux indicateurs pour prendre en charge la création et la vérification des revendications d’attestation en fonction des clés d’attestation dans la protection des clés VBS.

Voici types dwClaimType définis pour l’API :

Type de revendication Description
NCRYPT_CLAIM_VBS_ROOT Ce type indique que la revendication générée est produite par la clé racine VBS.
NCRYPT_CLAIM_VBS_IDENTITY Ce type indique que la revendication générée est produite par une identité/attestation VBS. Cela signifie que la revendication est produite par une clé VBS élevée avec l’indicateur d’attestation NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (voir les détails ci-dessous).

Voici les types de mémoires tampons à définir dans mémoire tampon pParameterList lors de la création d’une revendication d’attestation :

Type de mémoire tampon Description
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH Type de mémoire tampon à définir dans une mémoire tampon de paramètres lors de la création d’une revendication d’attestation dans NCryptCreateClaim. Il s’agit d’un type de paramètre obligatoire pour les revendications NCRYPT_CLAIM_VBS_IDENTITY.

Ce paramètre configure le type de type de fonction de hachage à utiliser via la création de la revendication d’attestation. Les valeurs de ce paramètre sont définies dans ncrypt.h (comme les constantes dans identificateurs d’algorithme 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 Type de mémoire tampon à définir dans une mémoire tampon de paramètres lors de la création d’une revendication d’attestation dans NCryptCreateClaim. Il s’agit d’un paramètre obligatoire dans le cas où la clé d’attestation dans la revendication NCRYPT_CLAIM_VBS_IDENTITY créée est une clé RSA.

Ce paramètre configure le schéma de remplissage du type de fonction signature à utiliser via la création de la revendication d’attestation. Les valeurs facultatives de ce paramètre sont définies dans (comme les constantes dwFlags dans NCryptSignHash) :

#define BCRYPT_PAD_PSS 0x00000008
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO Nouveau type de mémoire tampon à définir dans une mémoire tampon de paramètres lors de la création d’une revendication d’attestation dans NCryptCreateClaim. Il s’agit d’un paramètre obligatoire dans le cas où la clé d’attestation dans la revendication NCRYPT_CLAIM_VBS_IDENTITY créée est une clé RSA. Le paramètre est un pointeur vers une chaîne Unicode terminée par null qui identifie l’algorithme de chiffrement à utiliser pour créer le remplissage. Cet algorithme doit être un algorithme de hachage. Les valeurs de ce paramètre sont définies dans ncrypt.h (comme les constantes dans identificateurs d’algorithme 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 Nouveau type de mémoire tampon à définir dans une mémoire tampon de paramètres lors de la création d’une revendication d’attestation dans NCryptCreateClaim. Il s’agit d’un paramètre obligatoire dans le cas où la clé d’attestation dans la revendication NCRYPT_CLAIM_VBS_IDENTITY créée est une clé RSA.

Le paramètre représente une taille, en octets, du sel aléatoire à utiliser pour le remplissage.
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE Type de mémoire tampon à définir dans une mémoire tampon de paramètres lors de la création d’une revendication d’attestation dans NCryptCreateClaim. Ce paramètre est un alias pour NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCE.

Exemples

Cet exemple illustre l’utilisation du nouvel indicateur d’API NCRYPT_ALLOW_KEY_ATTESTATION_FLAG. En outre, la valeur nonce de la création de revendication est définie par le type de paramètre NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE.

L’exemple se compose de ces étapes principales :

  1. Une nouvelle clé d’attestation est créée. La clé est spécialisée à l’aide de la fonction API NCryptSetProperty. La génération d’une attestation est basée sur une clé de signature.
  2. Une revendication est créée pour une attestation supplémentaire. La revendication est associée à la clé d’attestation et à une clé VBS intégrée. La revendication peut être vérifiée dans NCryptVerifyClaim en fournissant la clé d’attestation.
  3. L’objet clé d’attestation est libéré pour éviter la fuite de mémoire.
// 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).
                    &params, // 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).
                    &params, // 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;
}

Cet exemple illustre l’utilisation de nouveaux paramètres d’API pour créer une clé de chiffrement à usage général et une revendication d’attestation associée. Cette clé à usage général est utilisée pour générer une revendication d’attestation.

Le type d’algorithme de hachage et le remplissage de la création de revendication sont définis dans les paramètres NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH et NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_[SCHEME/ALGO/SALT_SIZE] respectivement.

Veuillez noter que :

  • Le paramètre NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH est obligatoire uniquement pour les revendications NCRYPT_CLAIM_VBS_IDENTITY et sans signification dans d’autres types de revendications.
  • Le paramètre NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING est obligatoire uniquement pour les revendications NCRYPT_CLAIM_VBS_IDENTITY en cas de clé d’attestation RSA. Dans d’autres types de revendications, il n’est pas sensé.

La revendication nous permet de vérifier que la clé à usage général est associée à la clé d’attestation.

//
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.
                &params, // 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
                &params,
                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;

Exigences

Exigence Valeur
client minimum pris en charge Windows 10 [applications de bureau | Applications UWP]
serveur minimum pris en charge Windows Server 2016 [applications de bureau | Applications UWP]
plateforme cible Windows
d’en-tête ncrypt.h
bibliothèque Ncrypt.lib
DLL Ncrypt.dll