NCryptCreateClaimFn
コールバックシグネチャ
HRESULT NCryptCreateClaimFn(
NCRYPT_PROV_HANDLE hProv,
NCRYPT_KEY_HANDLE hSubjectKey,
NCRYPT_KEY_HANDLE hAuthorityKey,
DWORD dwClaimType,
BCryptBufferDesc* pParameterList,
BYTE* pbClaimBlob,
DWORD cbClaimBlob,
DWORD* pcbResult,
DWORD dwFlags
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| hProv | NCRYPT_PROV_HANDLE | |
| hSubjectKey | NCRYPT_KEY_HANDLE | クレームの作成対象となるサブジェクトキーのハンドルです。 |
| hAuthorityKey | NCRYPT_KEY_HANDLE | クレームの基になる authority キー (権限キー) のハンドルです。 |
| dwClaimType | DWORD | クレームの種類です。 |
| pParameterList | BCryptBufferDesc* | 省略可能なパラメーターリストです。 |
| pbClaimBlob | BYTE* | 作成されたクレーム BLOB の出力先です。 |
| cbClaimBlob | DWORD | pbClaimBlob バッファーのサイズ (バイト単位) です。 |
| pcbResult | DWORD* | 作成されたクレーム BLOB の出力です。 |
| dwFlags | DWORD | 現在、定義されているフラグはありません。dwFlags パラメーターには 0 を設定してください。 |
公式ドキュメント
キー構成証明クレームを作成します。
戻り値
関数の成功または失敗を示すステータスコードを返します。
解説(Remarks)
仮想化ベースのセキュリティ (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 バッファーに設定するバッファーの種類は次のとおりです。
[!div class="mx-tdBreakAll"]
バッファーの種類 説明 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_ALGORITHMNCRYPTBUFFER_ATTESTATION_STATEMENT_SIGNATURE_PADDING_SCHEME NCryptCreateClaim で構成証明クレームを作成するときに、パラメーターバッファーに設定するバッファーの種類です。作成する NCRYPT_CLAIM_VBS_IDENTITY クレームの構成証明キーが RSA キーである場合は必須のパラメーターです。
このパラメーターは、構成証明クレームの作成時に使用する署名関数のパディングスキームを設定します。このパラメーターに指定できる値はbcrypt.hで定義されています (NCryptSignHash の dwFlags 定数と同様です)。#define BCRYPT_PAD_PSS 0x00000008NCRYPTBUFFER_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_ALGORITHMNCRYPTBUFFER_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 の使用方法を示します。また、クレーム作成時のノンス値を NCRYPTBUFFER_ATTESTATION_STATEMENT_NONCE パラメーターの種類で設定しています。
この例は、次の主な手順で構成されます。
- 新しい構成証明キーを作成します。このキーは API 関数 NCryptSetProperty を使用して特殊化されます。構成証明の生成は署名キーに基づきます。
- 以降の構成証明のためにクレームを作成します。クレームは、構成証明キーと組み込みの 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;
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)