Fungsi NCryptVerifyClaim (ncrypt.h)

Memverifikasi klaim pengesahan kunci.

Sintaksis

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

Parameter

[in] hSubjectKey

Handel kunci subjek untuk klaim.

[in, optional] hAuthorityKey

Handel kunci otoritas untuk digunakan saat memverifikasi klaim. Parameter ini bersifat opsional karena kunci otoritas mandiri untuk jenis klaim tertentu.

[in] dwClaimType

Jenis klaim.

[in, optional] pParameterList

Daftar parameter opsional.

[in] pbClaimBlob

Blob klaim input.

[in] cbClaimBlob

Ukurannya, dalam byte, dari pbClaimBlob buffer.

[out] pOutput

Blob output.

[in] dwFlags

NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG adalah bendera baru yang akan ditetapkan selama verifikasi klaim yang dihasilkan VBS. Lihat bagian keterangan untuk informasi selengkapnya.

Saat ini tidak ada bendera lain yang ditentukan. Parameter dwFlags harus diatur ke untuk semua jenis verifikasi lainnya.

Mengembalikan nilai

Mengembalikan kode status yang menunjukkan keberhasilan atau kegagalan fungsi.

Berikut ini adalah beberapa kode kesalahan yang mungkin dikembalikan dari API verifikasi saat memverifikasi klaim pengesahan perlindungan kunci VBS:

Kode Pengembalian Arti
NTE_BAD_TYPE Parameter input jenis klaim berbeda dari jenis blob klaim input.
STATUS_BAD_DATA Blob klaim input tidak valid.
STATUS_NO_MEMORY Alokasi memori (diperlukan untuk verifikasi klaim) gagal.
STATUS_INVALID_PARAMETER Kehilangan parameter input wajib atau salah satu parameter memiliki nilai ilegal.
STATUS_FAIL_CHECK Pemeriksaan klaim blob input telah gagal.
NTE_BAD_VER Versi blob klaim tidak cocok dengan implementasi verifikasi.
NTE_BAD_FLAGS Bendera yang disediakan dalam dwFlags tidak didukung.

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 dan 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 memverifikasi klaim pengesahan:

  • NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS

    Struktur baru yang akan ditetapkan sebagai item NCryptBuffer jenis NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS di parameter output NCryptBufferDesc NCryptVerifyClaim dengan dwClaimType diatur ke NCRYPT_CLAIM_VBS_ROOT. Definisi strukturnya adalah:

    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;
    

    Struktur mencakup item-item ini:

    • ulKeyFlags – Kombinasi nilai NCRYPT_VBS_KEY_FLAG_* yang ditetapkan untuk kunci identitas.
    • ullTrustletId – Bilangan bulat pengidentifikasi yang dikodekan secara permanen dalam metadata kebijakan VBS Trustlet yang membuat klaim.
    • ulTrustletSecurityVersion – Nomor Versi Keamanan VBS Trustlet yang membuat klaim. Versi ini mencerminkan pembaruan keamanan mana yang telah diterapkan ke trustlet dan akibatnya menyiratkan tingkat keamanannya.
    • ulTrustletDebuggable – Indikasi jika VBS Trustlet yang membuat klaim dapat di-debug. Nilai 1 menunjukkan bahwa trustlet dapat di-debug dan 0 menunjukkan trustlet yang tidak dapat di-debug

    Jika item informatif lebih lanjut diperlukan di masa mendatang, maka struktur baru dan jenis struktur yang sesuai akan ditentukan.

    Nota

    Parameter output ini harus dirilis setelah tidak lagi dirujuk.

  • NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS

    Struktur baru yang akan ditetapkan sebagai item NCryptBuffer jenis NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS di parameter output NCryptBufferDesc NCryptVerifyClaim dengan dwClaimType diatur ke NCRYPT_CLAIM_VBS_IDENTITY. Definisi strukturnya adalah:

    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;
    

    Struktur mencakup item-item ini:

    • ulKeyFlags – Kombinasi nilai NCRYPT_VBS_KEY_FLAG_* yang ditetapkan untuk kunci identitas.
    • pszSignatureHashAlg - Penunjuk ke string Unicode dari algoritma hash tanda tangan klaim.
    • ulPaddingScheme - Skema Padding dari algoritma penandatanganan yang digunakan melalui pembuatan klaim di BCryptSignHash.
    • pszPaddingHashAlg - Penunjuk ke string Unicode dari algoritma hash padding klaim yang digunakan melalui pembuatan klaim di BCryptSignHash.
    • ulPaddingSalt - Garam Padding dari algoritma penandatanganan yang digunakan melalui pembuatan klaim di BCryptSignHash.

    Jika item informatif lebih lanjut diperlukan di masa mendatang, maka struktur baru dan jenis struktur yang sesuai akan ditentukan.

    Nota

    Parameter output ini harus dirilis setelah tidak lagi dirujuk. Kode sampel untuk merilis parameter ini diberikan dalam contoh kode di bawah ini.

  • NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS

    Jenis buffer baru yang akan diatur dalam parameter NCryptBuffer di NCryptBufferDesc*pOutput parameter NCryptVerifyClaim. Jenis ini menunjukkan bahwa NCryptBuffer menyertakan struktur data NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS.

  • NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS

    Jenis buffer baru yang akan diatur dalam parameter NCryptBuffer di NCryptBufferDesc*pOutput parameter NCryptVerifyClaim. Jenis ini menunjukkan bahwa NCryptBuffer menyertakan struktur data NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS.

  • NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG

    Ini adalah bendera baru yang akan diatur dalam parameter input dwFlags selama verifikasi klaim yang dihasilkan VBS. Ketika bendera ini diatur NCryptVerifyClaim menghasilkan parameter output NCryptBufferDesc dengan jenis buffer parameter NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS internal atau NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS.

    Tabel berikut menjelaskan hubungan antara jenis struktur data input dan output, dalam skenario yang berhasil dengan NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG:

    Masukan Hasil
    dwClaimType = NCRYPT_CLAIM_VBS_ROOT NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS jenis buffer dengan struktur informatif NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS internal.
    dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS jenis buffer dengan struktur informatif NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS internal.

Contoh

Contoh ini menggambarkan penggunaan API yang ada untuk memverifikasi klaim pengesahan yang dihasilkan dengan NCryptCreateClaim.

API verifikasi dapat dipanggil secara lokal (pada komputer yang menghasilkan blob klaim) atau dari jarak jauh. Prosedur verifikasi memerlukan elemen-elemen ini, sesuai dengan kunci pembuatan klaim:

  • Blob klaim
  • Blob kunci pengesahan publik
  • Blob kunci token publik (tujuan umum)

API verifikasi menghasilkan salah satu struktur informatif output NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS atau NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS jika bendera input NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG diatur. Memori struktur ini dibesarkan di akhir aliran kode untuk menghindari kebocoran memori.

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

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