Condividi tramite


Funzione NCryptCreateClaim (ncrypt.h)

Crea un'attestazione di attestazione della chiave.

Sintassi

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

Parametri

[in] hSubjectKey

Handle della chiave del soggetto per cui viene creata l'attestazione.

[in, optional] hAuthorityKey

Handle della chiave dell'autorità su cui si basa l'attestazione.

[in] dwClaimType

Tipo di attestazione.

[in, optional] pParameterList

Elenco di parametri facoltativo.

[out] pbClaimBlob

Output del BLOB di attestazioni creato.

[in] cbClaimBlob

Dimensioni, in byte, del buffer pbClaimBlob .

[out] pcbResult

Output del BLOB di attestazioni creato.

[in] dwFlags

Attualmente non sono definiti flag. Il parametro dwFlags deve essere impostato su .

Valore restituito

Restituisce un codice di stato che indica l'esito positivo o negativo della funzione.

Osservazioni

Protezione/attestazione di chiavi private tramite la sicurezza basata su virtualizzazione (VBS)

Nota

Le informazioni relative ai flag VBS riguardano il prodotto in versione non definitiva che potrebbe essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non fornisce alcuna garanzia, espressa o implicita, in relazione alle informazioni fornite qui.

Questa API consente di abilitare un'attestazione avanzata delle chiavi di sicurezza in base alla protezione della chiave VBS, un modulo Di Windows per la protezione/attestazione di chiavi private usando la sicurezza basata su vbs. L'attestazione di una chiave di sicurezza dimostra l'associazione di questa chiave a una chiave ancorata, ovvero una chiave di attestazione. Questa funzionalità può migliorare il livello di sicurezza della comunicazione tra entità diverse limitando l'utilizzo delle chiavi fuori contesto.

L'API definisce nuovi flag per supportare la creazione e la verifica delle attestazioni di attestazione in base alle chiavi di attestazione nella protezione della chiave VBS.

Di seguito sono riportati tipi di dwClaimType definiti per l'API:

Tipo di attestazione Descrizione
NCRYPT_CLAIM_VBS_ROOT Questo tipo indica che l'attestazione generata viene prodotta dalla chiave radice VBS.
NCRYPT_CLAIM_VBS_IDENTITY Questo tipo indica che l'attestazione generata viene prodotta da un'identità/attestazione VBS. Ciò significa che l'attestazione viene prodotta da una chiave VBS con privilegi elevati con il flag di attestazione NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (vedere i dettagli di seguito).

Di seguito sono riportati i tipi di buffer da impostare in buffer pParameterList durante la creazione di un'attestazione di attestazione:

Tipo di buffer Descrizione
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH Tipo di buffer da impostare in un buffer di parametri quando si crea un'attestazione di attestazione in NCryptCreateClaim. Si tratta di un tipo di parametro obbligatorio per NCRYPT_CLAIM_VBS_IDENTITY attestazioni.

Questo parametro configura il tipo di funzione hash da usare tramite la creazione dell'attestazione di attestazione. I valori per questo parametro vengono definiti in ncrypt.h (ad esempio le costanti in identificatori di 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 Tipo di buffer da impostare in un buffer di parametri quando si crea un'attestazione di attestazione in NCryptCreateClaim. Si tratta di un parametro obbligatorio nel caso in cui la chiave di attestazione nell'attestazione creata NCRYPT_CLAIM_VBS_IDENTITY sia una chiave RSA.

Questo parametro configura lo schema di spaziatura interna per il tipo di funzione di firma da usare tramite la creazione dell'attestazione. I valori facoltativi per questo parametro vengono definiti in (ad esempio le costanti dwFlags in NCryptSignHash):

#define BCRYPT_PAD_PSS 0x00000008
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO Nuovo tipo di buffer da impostare in un buffer di parametri quando si crea un'attestazione di attestazione in NCryptCreateClaim. Si tratta di un parametro obbligatorio nel caso in cui la chiave di attestazione nell'attestazione creata NCRYPT_CLAIM_VBS_IDENTITY sia una chiave RSA. Il parametro è un puntatore a una stringa Unicode con terminazione Null che identifica l'algoritmo di crittografia da usare per creare la spaziatura interna. Questo algoritmo deve essere un algoritmo hash. I valori per questo parametro vengono definiti in ncrypt.h (ad esempio le costanti in identificatori di 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 Nuovo tipo di buffer da impostare in un buffer di parametri quando si crea un'attestazione di attestazione in NCryptCreateClaim. Si tratta di un parametro obbligatorio nel caso in cui la chiave di attestazione nell'attestazione creata NCRYPT_CLAIM_VBS_IDENTITY sia una chiave RSA.

Il parametro rappresenta una dimensione, in byte, del sale casuale da utilizzare per la spaziatura interna.
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE Tipo di buffer da impostare in un buffer di parametri quando si crea un'attestazione di attestazione in NCryptCreateClaim. Questo parametro è un alias per NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCE.

Esempi

Questo esempio illustra l'utilizzo del nuovo flag API NCRYPT_ALLOW_KEY_ATTESTATION_FLAG. Inoltre, il valore nonce per la creazione dell'attestazione viene impostato dal tipo di parametro NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE.

L'esempio è costituito da questi passaggi principali:

  1. Viene creata una nuova chiave di attestazione. La chiave è specializzata usando la funzione API NCryptSetProperty. La generazione di un'attestazione si basa su una chiave di firma.
  2. Viene creata un'attestazione per un'ulteriore attestazione. L'attestazione è associata alla chiave di attestazione e a una chiave VBS predefinita. L'attestazione può essere verificata in NCryptVerifyClaim fornendo la chiave di attestazione.
  3. L'oggetto chiave di attestazione viene liberato per evitare perdite di memoria.
// 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;
}

Questo esempio seguente illustra l'utilizzo dei nuovi parametri API per la creazione di una chiave crittografica per utilizzo generico e un'attestazione di attestazione associata. Questa chiave per utilizzo generico viene usata per generare un'attestazione di attestazione.

Il tipo di algoritmo hash e la spaziatura interna per la creazione dell'attestazione vengono impostati rispettivamente nei parametri NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH e NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_[SCHEME/ALGO/SALT_SIZE].

Si noti che:

  • Il parametro NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH è obbligatorio solo per NCRYPT_CLAIM_VBS_IDENTITY attestazioni e senza significato in altri tipi di attestazioni.
  • Il parametro NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING è obbligatorio solo per NCRYPT_CLAIM_VBS_IDENTITY attestazioni in caso di chiave di attestazione RSA. In altri tipi di attestazioni è privo di significato.

L'attestazione consente di verificare che la chiave per utilizzo generico sia associata alla chiave di attestazione.

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

Fabbisogno

Requisito Valore
client minimo supportato Windows 10 [app desktop | App UWP]
server minimo supportato Windows Server 2016 [app desktop | App UWP]
piattaforma di destinazione Finestre
intestazione ncrypt.h
libreria Ncrypt.lib
dll Ncrypt.dll