Fungsi NCryptCreateClaim (ncrypt.h)

Membuat klaim pengesahan kunci.

Sintaksis

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

Parameter

[in] hSubjectKey

Kunci subjek menangani klaim dibuat.

[in, optional] hAuthorityKey

Kunci otoritas menangani bahwa klaim didasarkan pada.

[in] dwClaimType

Jenis klaim.

[in, optional] pParameterList

Daftar parameter opsional.

[out] pbClaimBlob

Output blob klaim yang dibuat.

[in] cbClaimBlob

Ukurannya, dalam byte, dari pbClaimBlob buffer.

[out] pcbResult

Output blob klaim yang dibuat.

[in] dwFlags

Saat ini tidak ada bendera yang ditentukan. Parameter dwFlags harus diatur ke .

Mengembalikan nilai

Mengembalikan kode status yang menunjukkan keberhasilan atau kegagalan fungsi.

Komentar

Melindungi/membuktikan kunci privat menggunakan Virtualization Based Security (VBS)

Nota

Informasi mengenai bendera VBS berkaitan dengan produk prarilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersurat maupun tersirat, sehubungan dengan informasi yang diberikan di sini.

API ini membantu mengaktifkan pengesahan lanjutan kunci keamanan berdasarkan perlindungan kunci VBS, modul Windows untuk melindungi/membuktikan kunci privat menggunakan VBS. Pengesahan kunci keamanan membuktikan asosiasi kunci ini ke kunci berlabuh, alias kunci pengesahan. Kemampuan ini dapat meningkatkan tingkat keamanan komunikasi antara entitas yang berbeda dengan membatasi penggunaan kunci konteks.

API mendefinisikan bendera baru untuk mendukung pembuatan dan verifikasi klaim pengesahan berdasarkan kunci pengesahan dalam perlindungan kunci VBS.

Berikut ini adalah jenis dwClaimType yang ditentukan untuk API:

Jenis Klaim Deskripsi
NCRYPT_CLAIM_VBS_ROOT Jenis ini menunjukkan bahwa klaim yang dihasilkan dihasilkan oleh kunci akar VBS.
NCRYPT_CLAIM_VBS_IDENTITY Jenis ini menunjukkan bahwa klaim yang dihasilkan dihasilkan oleh identitas/pengesahan VBS. Ini berarti bahwa klaim dihasilkan oleh kunci VBS yang ditinggikan dengan bendera pengesahan NCRYPT_ALLOW_KEY_ATTESTATION_FLAG (lihat detail di bawah).

Berikut ini adalah jenis buffer yang akan diatur dalam buffer pParameterList saat membuat klaim pengesahan:

Jenis Buffer Deskripsi
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH Jenis buffer yang akan diatur dalam buffer parameter saat membuat klaim pengesahan di NCryptCreateClaim. Ini adalah jenis parameter wajib untuk klaim NCRYPT_CLAIM_VBS_IDENTITY.

Parameter ini mengonfigurasi jenis fungsi hash yang akan digunakan melalui pembuatan klaim pengesahan. Nilai untuk parameter ini didefinisikan dalam ncrypt.h (seperti konstanta di Pengidentifikasi Algoritma 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 Jenis buffer yang akan diatur dalam buffer parameter saat membuat klaim pengesahan di NCryptCreateClaim. Ini adalah parameter wajib jika kunci pengesahan dalam klaim NCRYPT_CLAIM_VBS_IDENTITY yang dibuat adalah kunci RSA.

Parameter ini mengonfigurasi skema padding untuk jenis fungsi tanda tangan yang akan digunakan melalui pembuatan klaim pengesahan. Nilai opsional untuk parameter ini didefinisikan dalam bcrypt.h (seperti dwFlags konstanta di NCryptSignHash):

#define BCRYPT_PAD_PSS 0x00000008
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO Jenis buffer baru yang akan diatur dalam buffer parameter saat membuat klaim pengesahan di NCryptCreateClaim. Ini adalah parameter wajib jika kunci pengesahan dalam klaim NCRYPT_CLAIM_VBS_IDENTITY yang dibuat adalah kunci RSA. Parameter adalah penunjuk ke string Unicode null-terminated yang mengidentifikasi algoritma kriptografi yang akan digunakan untuk membuat padding. Algoritma ini harus berupa algoritma hash. Nilai untuk parameter ini didefinisikan dalam ncrypt.h (seperti konstanta di Pengidentifikasi Algoritma 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 Jenis buffer baru yang akan diatur dalam buffer parameter saat membuat klaim pengesahan di NCryptCreateClaim. Ini adalah parameter wajib jika kunci pengesahan dalam klaim NCRYPT_CLAIM_VBS_IDENTITY yang dibuat adalah kunci RSA.

Parameter mewakili ukuran, dalam byte, dari garam acak yang digunakan untuk padding.
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE Jenis buffer yang akan diatur dalam buffer parameter saat membuat klaim pengesahan di NCryptCreateClaim. Parameter ini adalah alias untuk NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCE.

Contoh

Contoh ini mengilustrasikan penggunaan bendera API baru NCRYPT_ALLOW_KEY_ATTESTATION_FLAG. Selain itu, nilai nonce untuk pembuatan klaim diatur oleh jenis parameter NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE.

Contohnya terdiri dari langkah-langkah utama ini:

  1. Kunci pengesahan baru dibuat. Kunci ini dikhususkan menggunakan fungsi API NCryptSetProperty. Pembuatan pengesahan didasarkan pada kunci penandatanganan.
  2. Klaim dibuat untuk pengesahan lebih lanjut. Klaim ini dikaitkan dengan kunci pengesahan dan dengan kunci VBS bawaan. Klaim dapat diverifikasi di NCryptVerifyClaim dengan memberikan kunci pengesahan.
  3. Objek kunci pengesahan dibesarkan untuk menghindari kebocoran memori.
// 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;
}

Contoh berikutnya ini menggambarkan penggunaan parameter API baru untuk membuat kunci kriptografi tujuan umum dan klaim pengesahan terkait. Kunci tujuan umum ini digunakan untuk menghasilkan klaim pengesahan.

Jenis algoritma hash dan padding untuk pembuatan klaim diatur dalam parameter NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH dan NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_[SCHEME/ALGO/SALT_SIZE].

Harap dicatat bahwa:

  • Parameter NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH hanya wajib untuk klaim NCRYPT_CLAIM_VBS_IDENTITY dan tidak berarti dalam jenis klaim lainnya.
  • Parameter NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING hanya wajib untuk klaim NCRYPT_CLAIM_VBS_IDENTITY jika terjadi kunci pengesahan RSA. Dalam jenis klaim lain itu tidak ada artinya.

Klaim memungkinkan kami memverifikasi bahwa kunci tujuan umum dikaitkan dengan kunci pengesahan.

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

Persyaratan

Syarat Nilai
klien minimum yang didukung Windows 10 [aplikasi desktop | Aplikasi UWP]
server minimum yang didukung Windows Server 2016 [aplikasi desktop | Aplikasi UWP]
Platform Target Windows
Header ncrypt.h
Pustaka Ncrypt.lib
DLL Ncrypt.dll