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 で定義されます (NCryptSignHashの dwFlags 定数など)。#define BCRYPT_PAD_PSS 0x00000008 |
NCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_ALGO | NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファーに設定 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で構成証明要求を作成するときにパラメーター バッファーに設定 このパラメーターは、パディングに使用するランダムソルトのサイズをバイト単位で表します。 |
NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE | NCryptCreateClaimで構成証明要求を作成するときにパラメーター バッファー |
例
この例では、新しい API フラグ NCRYPT_ALLOW_KEY_ATTESTATION_FLAGの使用方法を示します。 さらに、要求の作成の nonce 値は、NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE パラメーターの種類によって設定されます。
この例は、次の主要な手順で構成されています。
- 新しい構成証明キーが作成されます。 キーは、NCryptSetProperty
API 関数を使用して特殊化されます。 構成証明の生成は、署名キーに基づいています。 - さらに構成証明を行う要求が作成されます。 要求は構成証明キーと組み込みの VBS キーに関連付けられています。 要求は、構成証明キー 指定することで、NCryptVerifyClaim で検証できます。
- メモリ リークを回避するために、構成証明キー オブジェクトが解放されます。
// 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).
¶ms, // 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).
¶ms, // 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.
¶ms, // 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
¶ms,
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 |