次の方法で共有


NCryptCreateClaim 関数 (ncrypt.h)

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

構文

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

パラメーター

[in] hSubjectKey

要求が作成されるサブジェクト キー ハンドル。

[in, optional] hAuthorityKey

要求の基になっている機関キー ハンドル。

[in] dwClaimType

要求の種類。

[in, optional] pParameterList

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

[out] pbClaimBlob

作成された要求 BLOB の出力。

[in] cbClaimBlob

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

[out] pcbResult

作成された要求 BLOB の出力。

[in] dwFlags

現在、フラグは定義されていません。 dwFlags パラメーターを 0に設定する必要があります。

戻り値

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

備考

仮想化ベースのセキュリティ (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 バッファー 設定するバッファーの種類を次に示します。

バッファーの種類 形容
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファーに設定するバッファーの種類。 これは、NCRYPT_CLAIM_VBS_IDENTITY 要求の必須パラメーター型です。

このパラメーターは、構成証明要求の作成で使用するハッシュ関数型の型を構成します。 このパラメーターの値は、ncrypt.h で定義されます (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 NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファーに設定するバッファーの種類。 これは、作成された NCRYPT_CLAIM_VBS_IDENTITY 要求の構成証明キーが RSA キーである場合の必須パラメーターです。

このパラメーターは、構成証明要求の作成で使用される署名関数の種類の埋め込みスキームを構成します。 このパラメーターの省略可能な値は、bcrypt.h で定義されます (NCryptSignHashdwFlags 定数など)。

#define BCRYPT_PAD_PSS 0x00000008
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファーに設定 新しいバッファーの種類。 これは、作成された NCRYPT_CLAIM_VBS_IDENTITY 要求の構成証明キーが RSA キーである場合の必須パラメーターです。 このパラメーターは、埋め込みの作成に使用する暗号アルゴリズムを識別する null で終わる Unicode 文字列へのポインターです。 このアルゴリズムはハッシュ アルゴリズムである必要があります。 このパラメーターの値は、ncrypt.h で定義されます (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 NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファーに設定 新しいバッファーの種類。 これは、作成された NCRYPT_CLAIM_VBS_IDENTITY 要求の構成証明キーが RSA キーである場合の必須パラメーターです。

このパラメーターは、パディングに使用するランダムソルトのサイズをバイト単位で表します。
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファー 設定するバッファーの種類。 このパラメーターは、NCRYPTBUFFER_CLAIM_KEYATTESTATION_NONCEのエイリアスです。

この例では、新しい API フラグ NCRYPT_ALLOW_KEY_ATTESTATION_FLAGの使用方法を示します。 さらに、要求の作成の nonce 値は、NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE パラメーターの種類によって設定されます。

この例は、次の主要な手順で構成されています。

  1. 新しい構成証明キーが作成されます。 キーは、NCryptSetPropertyAPI 関数を使用して特殊化されます。 構成証明の生成は、署名キーに基づいています。
  2. さらに構成証明を行う要求が作成されます。 要求は構成証明キーと組み込みの VBS キーに関連付けられています。 要求は、構成証明キー 指定することで、NCryptVerifyClaim で検証できます。
  3. メモリ リークを回避するために、構成証明キー オブジェクトが解放されます。
// 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;
}

次の例では、汎用暗号化キーと関連する構成証明要求を作成するための新しい API パラメーターの使用方法を示します。 この汎用キーは、構成証明要求を生成するために使用されます。

要求作成のハッシュ アルゴリズムの種類とパディングは、それぞれ NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH パラメーターと NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ [SCHEME/ALGO/SALT_SIZE] パラメーターで設定されます。

次の点に注意してください。

  • NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_HASH パラメーターは、NCRYPT_CLAIM_VBS_IDENTITY 要求に対してのみ必須であり、他の種類の要求では意味がありません。
  • NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING パラメーターは、RSA 構成証明キーの場合に NCRYPT_CLAIM_VBS_IDENTITY 要求に対してのみ必須です。 他の種類のクレームでは意味がありません。

要求を使用すると、汎用キーが構成証明キーに関連付けられていることを確認できます。

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

必要条件

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