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 | 필수 입력 매개 변수가 없거나 매개 변수 중 하나에 잘못된 값이 있습니다. |
STATUS_FAIL_CHECK | 입력 Blob 클레임의 검사가 실패했습니다. |
NTE_BAD_VER | 클레임 Blob 버전이 확인 구현과 일치하지 않습니다. |
NTE_BAD_FLAGS | dwFlags 제공된 플래그는 지원되지 않습니다. |
발언
VBS(가상화 기반 보안)를 사용하여 프라이빗 키 보호/증명
메모
VBS 플래그에 대한 정보는 상용 출시 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보와 관련하여 명시적이거나 묵시적인 보증을 하지 않습니다.
이 API는 VBS 키를 보호하고 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 버퍼에서 설정할 버퍼 형식입니다.
NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS
dwClaimTypeNCRYPT_CLAIM_VBS_ROOT설정하여 NCryptVerifyClaimNCryptBufferDesc 출력 매개 변수에 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
dwClaimType이 항목으로 설정할 새 구조체입니다. 구조 정의는 다음과 같습니다.NCRYPT_CLAIM_VBS_IDENTITY 설정된NCryptVerifyClaim NCryptBufferDesc 출력 매개 변수에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 - 클레임 서명 해시 알고리즘의 유니코드 문자열에 대한 포인터입니다.
- ulPaddingScheme - BCryptSignHash클레임 생성을 통해 사용된 서명 알고리즘의 패딩 체계입니다.
- pszPaddingHashAlg - BCryptSignHash클레임 생성을 통해 사용되는 클레임 패딩 해시 알고리즘의 유니코드 문자열에 대한 포인터입니다.
- ulPaddingSalt - BCryptSignHash클레임 생성을 통해 사용된 서명 알고리즘의 패딩 솔트입니다.
나중에 추가 정보 항목이 필요한 경우 새 구조체와 해당 구조체 형식이 정의됩니다.
메모
이 출력 매개 변수는 더 이상 참조되지 않은 후에 해제해야 합니다. 이 매개 변수를 해제하기 위한 샘플 코드는아래
코드 예제에 제공됩니다. NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_ROOT_DETAILS
NCryptVerifyClaimNCryptBufferDesc*pOutput 매개 변수의 매개 변수 NCryptBuffer 설정할 새 버퍼 형식입니다. 이 형식은 NCryptBuffer 데이터 구조 NCRYPT_VBS_ROOT_KEY_ATTESTATION_CLAIM_DETAILS포함했음을 나타냅니다.
NCRYPTBUFFER_VBS_ATTESTATION_STATEMENT_IDENTITY_DETAILS
NCryptVerifyClaimNCryptBufferDesc*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 중 하나를 생성합니다. 이러한 구조의 메모리는 메모리 누수 방지를 위해 코드 흐름의 끝에서 해제됩니다.
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 앱] |
대상 플랫폼 | Windows |
헤더 | ncrypt.h |
라이브러리 | Ncrypt.lib |
DLL | Ncrypt.dll |