次の方法で共有


NCryptVerifyClaim 関数 (ncrypt.h)

キー構成証明要求を検証します。

構文

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

パラメーター

[in] hSubjectKey

要求のサブジェクト キー ハンドル。

[in, optional] hAuthorityKey

要求を検証するときに使用する機関キー ハンドル。 このパラメーターは省略可能です。これは、特定の種類の要求に対して権限キーが自己完結型であるためです。

[in] dwClaimType

要求の種類。

[in, optional] pParameterList

省略可能なパラメーター リスト。

[in] pbClaimBlob

入力要求 BLOB。

[in] cbClaimBlob

pbClaimBlob バッファーのサイズ (バイト単位)。

[out] pOutput

出力 BLOB。

[in] dwFlags

NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG は、VBS によって生成された要求の検証中に設定される新しいフラグです。 詳細については、解説 セクションを参照してください。

現在、他のフラグは定義されていません。 dwFlags パラメーターは、他のすべての検証の種類に対して 0 に設定する必要があります。

戻り値

関数の成功または失敗を示す状態コードを返します。

VBS キー保護構成証明要求を検証するときに検証 API から返される可能性があるエラー コードの一部を次に示します。

リターン コード 意味
NTE_BAD_TYPE 要求の種類の入力パラメーターは、入力要求 BLOB の種類とは異なります。
STATUS_BAD_DATA 入力要求 BLOB が無効です。
STATUS_NO_MEMORY メモリ (要求の検証に必要) の割り当てに失敗しました。
STATUS_INVALID_PARAMETER 必須の入力パラメーターまたはパラメーターの 1 つが見つからない場合、値が正しくありません。
STATUS_FAIL_CHECK 入力 BLOB 要求のチェックに失敗しました。
NTE_BAD_VER 要求 BLOB のバージョンが検証の実装と一致しません。
NTE_BAD_FLAGS dwFlags で提供されるフラグはサポートされていません。

備考

仮想化ベースのセキュリティ (VBS) を使用した秘密キーの保護/構成証明

手記

VBS フラグに関する情報は、商用リリース前に大幅に変更される可能性があるプレリリース製品に関連しています。 Microsoft は、ここで提供される情報に関して明示的または黙示的な保証を行いません。

この API は、VBS キー保護に基づくセキュリティ キーの高度な構成証明を有効にするのに役立ちます。これは、VBS を使用して秘密キーを保護および構成証明するための Windows モジュールです。 セキュリティ キーの構成証明は、このキーとアンカー キー (構成証明キー) の関連付けを証明します。 この機能により、コンテキスト キーの使用を制限することで、異なるエンティティ間の通信のセキュリティ レベルが強化される場合があります。

この API は、VBS キー保護の構成証明キーに基づく構成証明要求の作成と検証をサポートする新しいフラグを定義します。

API に対して定義されている dwClaimType 型 を次に示します。

要求の種類 形容
NCRYPT_CLAIM_VBS_ROOT この型は、生成された要求が VBS ルート キーによって生成されることを示します。
NCRYPT_CLAIM_VBS_IDENTITY この型は、生成された要求が VBS ID/構成証明によって生成されることを示します。 これは、要求が構成証明フラグ NCRYPT_ALLOW_KEY_ATTESTATION_FLAG で昇格された VBS キーによって生成されることを意味します (詳細については、以下を参照してください)。

構成証明要求を検証するときに pParameterList バッファー 設定するバッファーの種類を次に示します。

  • NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS

    dwClaimTypeNCRYPT_CLAIM_VBS_ROOTに設定された NCryptBufferDesc の出力パラメーター NCryptBufferDesc NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS 型の NCryptBuffer 項目として設定される新しい構造体。 構造体の定義は次のとおりです。

    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;
    

    構造には、次の項目が含まれます。

    • ulKeyFlags – ID キーに設定された NCRYPT_VBS_KEY_FLAG_* 値の組み合わせ。
    • ullTrustletId – 要求を作成した VBS Trustlet のポリシー メタデータ内のハードコーディングされた識別子整数。
    • ulTrustletSecurityVersion – 要求を作成した VBS Trustlet のセキュリティ バージョン番号。 このバージョンでは、どのセキュリティ更新プログラムが trustlet に適用されたかが反映され、その結果、セキュリティのレベルが示されます。
    • ulTrustletDebuggable – 要求を作成した VBS Trustlet がデバッグ可能かどうかを示します。 1 値はトラストレットがデバッグ可能であることを示し、0 はデバッグ不可能なトラストレットを示します

    今後さらに有益な項目が必要な場合は、新しい構造体と対応する構造体型が定義されます。

    手記

    この出力パラメーターは、参照されなくなった後に解放する必要があります。

  • NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS

    NCryptVerifyClaim の出力パラメーター dwClaimType NCRYPT_CLAIM_VBS_IDENTITYに設定 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS 型の NCryptBuffer 項目として設定する新しい構造体。 構造体の定義は次のとおりです。

    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;
    

    構造には、次の項目が含まれます。

    • ulKeyFlags – ID キーに設定された NCRYPT_VBS_KEY_FLAG_* 値の組み合わせ。
    • pszSignatureHashAlg - クレーム署名ハッシュ アルゴリズムの Unicode 文字列へのポインター。
    • ulPaddingScheme - BCryptSignHashでの要求の作成によって使用された署名アルゴリズムのパディング スキーム
    • pszPaddingHashAlg - BCryptSignHashでの要求の作成で使用される要求パディング ハッシュ アルゴリズムの Unicode 文字列へのポインター。
    • ulPaddingSalt - BCryptSignHashでの要求の作成で使用された署名アルゴリズムのパディングソルト。

    今後さらに有益な項目が必要な場合は、新しい構造体と対応する構造体型が定義されます。

    手記

    この出力パラメーターは、参照されなくなった後に解放する必要があります。 このパラメーターを解放するためのサンプル コードは、次のコード例で示します。

  • NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS

    NCryptVerifyClaimの NCryptBufferDesc*pOutput パラメーター NCryptBuffer のパラメーターに設定する新しいバッファーの種類。 この型は、NCryptBuffer にデータ構造 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILSが含まれていることを示します。

  • NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS

    NCryptVerifyClaimの NCryptBufferDesc*pOutput パラメーター NCryptBuffer のパラメーターに設定する新しいバッファーの種類。 この型は、NCryptBuffer にデータ構造 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILSが含まれていることを示します。

  • NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG

    これは、VBS によって生成された要求の検証中に、dwFlags 入力パラメーターで設定される新しいフラグです。 このフラグが NCryptVerifyClaim 設定されると、内部 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS または NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS パラメーター バッファー型を持つ NCryptBufferDesc 出力パラメーターが生成されます。

    次の表では、NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAGを使用した成功したシナリオにおける入力データ構造と出力データ構造の型の関係について説明します。

    インプット アウトプット
    dwClaimType = NCRYPT_CLAIM_VBS_ROOT 内部 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS 情報構造を持つバッファー型 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS します。
    dwClaimType = NCRYPT_CLAIM_VBS_IDENTITY 内部 NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS 情報構造を持つバッファー型 NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS します。

この例では、既存の API を使用して、NCryptCreateClaimで生成された構成証明要求を検証する方法を示します。

検証 API は、ローカル (要求 BLOB を生成したマシン上) またはリモートで呼び出すことができます。 検証手順には、要求生成キーに対応する次の要素が必要です。

  • 要求 BLOB
  • 公開構成証明キー BLOB
  • パブリック トークン (汎用) キー BLOB

検証 API は、入力フラグ NCRYPT_VBS_RETURN_CLAIM_DETAILS_FLAG が設定されている場合に NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS または NCRYPT_VBS_IDENTITY_KEY_ATTESTATION_CLAIM_DETAILS 出力情報構造体の 1 つを生成します。 これらの構造体のメモリは、メモリ リークを回避するために、コード フローの最後に解放されます。

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

必要条件

要件 価値
サポートされる最小クライアント Windows 10 [デスクトップ アプリ |UWP アプリ]
サポートされる最小サーバー Windows Server 2016 [デスクトップ アプリ |UWP アプリ]
ターゲット プラットフォーム の ウィンドウズ
ヘッダー ncrypt.h
ライブラリ Ncrypt.lib
DLL Ncrypt.dll