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를 사용하여 프라이빗 키를 보호/증명하기 위한 Windows 모듈인 VBS 키 보호를 기반으로 보안 키의 고급 증명을 사용하도록 설정하는 데 도움이 됩니다. 보안 키의 증명은 이 키와 고정된 키, 즉 증명 키의 연결을 증명합니다. 이 기능은 컨텍스트 외부 키의 사용을 제한하여 서로 다른 엔터티 간의 통신 보안 수준을 향상시킬 수 있습니다.
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로 끝나는 유니코드 문자열에 대한 포인터입니다. 이 알고리즘은 해시 알고리즘이어야 합니다. 이 매개 변수의 값은 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 매개 변수 형식에 의해 설정됩니다.
이 예제는 다음 주요 단계로 구성됩니다.
- 새 증명 키가 만들어집니다. 키는 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 앱] |
대상 플랫폼 | Windows |
헤더 | ncrypt.h |
라이브러리 | Ncrypt.lib |
DLL | Ncrypt.dll |