VBS(가상화 기반 보안) Enclave에 대한 개발 가이드
적용 대상:✅ Windows 11 빌드 26100.2314 이상 ✅ Windows Server 2025 이상
이 개발 가이드에서는 기본 VBS Enclave를 빌드, 서명 및 디버그하는 방법을 설명합니다.
필수 조건
VBS Enclave를 시작하려면 다음 요구 사항을 충족해야 합니다.
- VBS Enclave 개요에서 디바이스 요구 사항을 보고 충족합니다.
- VBS Enclave 개요에서 개발 필수 구성 요소를 보고 충족합니다.
- Visual Studio 설치 관리자를 통해 C++ 워크로드를 사용하여 데스크톱 개발을 설치하는 것이 좋습니다. Windows SDK(소프트웨어 개발 키트)를 포함하여 필요한 모든 도구를 설치합니다.
- GitHub에서 샘플 코드를 다운로드합니다. Enclave에 함수를 호출하는 방법을 포함하여 VBS Enclave의 수명 주기를 보여 줍니다.
- 모든 enclave에는 호스트 앱이 있어야 합니다. 샘플 코드에는 Enclave 호스트와 테스트 enclave라는 두 개의 프로젝트가 있는 Visual Studio 솔루션이 포함되어 있습니다.
시작
위의 필수 구성 요소를 충족한 후에는 Visual Studio의 VbsEnclave 샘플에서 솔루션 파일을 열고 컴파일할 수 있어야 합니다. 해당 enclave와 함께 테스트 애플리케이션을 만듭니다. 그러나 enclave가 유효한 인증서로 서명될 때까지 애플리케이션을 성공적으로 실행할 수 없습니다.
이 가이드에서는 개발 머신에서 기본 VBS Enclave를 빌드하는 방법을 자세히 설명합니다. VBS Enclave를 빌드하는 단계는 다음과 같습니다.
- VBS enclave DLL 및 해당 호스트 애플리케이션 작성
- DLL 및 호스트 컴파일
- VBS enclave DLL 서명
- VBS Enclave 디버그
먼저 enclave의 수명 주기를 이해하겠습니다. enclave API는 다음 순서로 호출됩니다.
1단계: VBS Enclave 작성
샘플 코드를 검토하고 VBS Enclave를 사용하는 애플리케이션을 작성하는 방법을 이해해 보겠습니다.
Enclave 호스트 작성
VBS enclave DLL은 단순히 DLL이므로 호스트 애플리케이션이 필요합니다. 호스트 애플리케이션은 표준 Windows 애플리케이션에 지나지 않습니다. VBS enclave를 사용하려면 호스트가 enclaveapi.h 헤더의 Windows enclave API를 사용해야 합니다. 호스트 애플리케이션에 포함 windows.h
하면 이러한 API에 대한 액세스 권한이 부여됩니다.
테스트 Enclave에 로드할 DLL 작성
아래 단계와 함께 수행하려면 테스트 Enclave 프로젝트의 샘플 코드를 참조하세요.
enclave 샘플에서는 입력 0xDADAF00D
을 XOR하고 결과를 반환하는 간단한 enclave를 만듭니다. 이 작업을 수행하는 방법을 세분화해 보겠습니다.
를 포함하여
winenclave.h
시작합니다. 샘플 코드에서 다음을 참조하세요Samples/VbsEnclave/Test enclave/precomp.h
.#include <winenclave.h>
winenclave.h
는 VBS enclave에 대한 중앙 포함 파일이며 그 자체에는 다음이ntenclv.h
winenclaveapi.h
포함됩니다windows.h
.enclave에 로드된 모든 DLL에는 구성이 필요합니다. 이 구성은 IMAGE_ENCLAVE_CONFIG 형식이라는
__enclave_config
전역const
변수를 사용하여 정의됩니다. 샘플 코드에서 다음을 참조하세요Samples/VbsEnclave/Test enclave/enclave.c
.const IMAGE_ENCLAVE_CONFIG __enclave_config = { sizeof(IMAGE_ENCLAVE_CONFIG), IMAGE_ENCLAVE_MINIMUM_CONFIG_SIZE, IMAGE_ENCLAVE_POLICY_DEBUGGABLE, // DO NOT SHIP DEBUGGABLE ENCLAVES TO PRODUCTION 0, 0, 0, { 0xFE, 0xFE }, // family id { 0x01, 0x01 }, // image id 0, // version 0, // SVN 0x10000000, // size 16, // number of threads IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE };
참고 항목
enclave당 하나의 기본 이미지만 있을 수 있습니다. 여러 기본 이미지를 로드하는 경우 먼저 로드된 이미지가 기본 이미지로 처리되고 나머지는 종속성으로 처리됩니다. 이 샘플에서는 enclave 플랫폼 DLL 이외의 종속성이 없습니다.
함수는
DllMain()
필수이며 enclave에 대한 진입점을 정의합니다. 이 호출은 .을 수행하는 동안InitializeEnclave()
호출합니다. 샘플 코드에서 .를 참조하세요Samples/VbsEnclave/Test enclave/enclave.c
.BOOL DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD dwReason, _In_ LPVOID lpvReserved ) { UNREFERENCED_PARAMETER(hinstDLL); UNREFERENCED_PARAMETER(lpvReserved); if (dwReason == DLL_PROCESS_ATTACH) { InitialCookie = 0xDADAF00D; } return TRUE; }
호스트 애플리케이션에서 호출되는 enclave 내의 모든 함수를 내보내고 LPENCLAVE_ROUTINE 형식이어야 합니다. 함수 서명은 다음과 같습니다.
void* CALLBACK enclaveFunctionName(_In_ void* Context)
샘플 코드에서 .를 참조하세요
Samples/VbsEnclave/Test enclave/enclave.c
.void* CALLBACK CallEnclaveTest( _In_ void* Context ) { WCHAR String[32]; swprintf_s(String, ARRAYSIZE(String), L"%s\n", L"CallEnclaveTest started"); OutputDebugStringW(String); return (void*)((ULONG_PTR)(Context) ^ InitialCookie); }
참고 항목
주 Enclave 이미지에서 내보낸 함수만 호스트 애플리케이션에서 액세스할 수 있습니다.
그런 다음 파일을 사용하여 함수를
.DEF
내보낼 수 있습니다. 샘플 코드에서 .를 참조하세요Samples/VbsEnclave/Test enclave/vbsenclave.def
. 자세한 내용은 DEF 파일을 사용하여 DLL에서 내보내기를 참조 하세요.
기본 VBS enclave DLL을 작성하는 방법입니다.
2단계: VBS Enclave 컴파일
이제 VBS enclave DLL을 작성했으므로 컴파일해 보겠습니다.
Enclave 호스트 컴파일
호스트 앱을 컴파일하는 것은 Windows 애플리케이션을 컴파일하는 것과 동일하지만 연결하는 동안 종속성 목록에 추가 onecore.lib
됩니다.
테스트 Enclave DLL 컴파일
테스트 enclave DLL을 빌드하려면 먼저 컴파일러 및 링커 구성에 대한 몇 가지 변경이 필요합니다.
MSVC 링커는 enclave 구성 세부 정보를 선택하는 플래그를 제공합니다
/ENCLAVE
./ENCLAVE
플래그는 증분 연결과 호환되지 않으므로 설정/INCREMENTAL:NO
해야 합니다.[디버그 구성만]
/EDITANDCONTINUE
와 호환되지/INCREMENTAL:NO
않으므로 컴파일러에서/ZI
디버그 정보 형식 대신 사용합니다/Zi
.[디버그 구성만] 기본 런타임 검사 구성을 기본값으로 설정해야 합니다. 런타임 오류 검사는 VBS Enclave에서 지원되지 않습니다.
enclave DLL의 디지털 서명은 로드 시 확인해야 하며 링커에서 플래그를
/INTEGRITYCHECK
설정해야 합니다.Enclave DLL은 링커에서 플래그를 사용하는
/GUARD:MIXED
CFG(Control Flow Guard)에 대해 계측되어야 합니다.Enclave에는 고유한 버전의 플랫폼, 시작, 런타임 및 UCRT 라이브러리가 있습니다. enclave가 아닌 버전을 연결하지 않도록 하려면 플래그를
/NODEFAULTLIB
사용합니다. 그 후 . 아래에AdditionalDependencies
올바른 라이브러리를 추가합니다. 샘플 코드에서 이러한 라이브러리는 VBS_Enclave_Dependencies 매크로 아래에 캡슐화됩니다. 다음은 VBS enclave 라이브러리입니다.libcmt.lib
및libvcruntime.lib
- Visual C++ 빌드 도구가 있는 폴더에 있는enclave
CRT(C 런타임) 및 C++ 표준 라이브러리(STL) .lib 파일을 참조하세요.vertdll.lib
및bcrypt.lib
- Windows SDK 라이브러리가um
있는 폴더에 있습니다.ucrt.lib
- Windows SDK 라이브러리가ucrt_enclave
있는 폴더에 있습니다.
참고 항목
다른 플랫폼 라이브러리는 VBS Enclave 내에서 지원되지 않습니다.
요약하면 다음과 같은 변경이 필요합니다.
컴파일러(디버그 구성에만 해당):
- 디버그 정보 형식:
/Zi
- 기본 런타임 검사:
Default
링커:
/ENCLAVE
/NODEFAULTLIBS
+AdditionalDependencies
/INCREMENTAL:NO
/INTEGRITYCHECK
/GUARD:MIXED
이제 enclave DLL을 컴파일할 수 있습니다.
VEIID를 사용하여 보안 설정
VEIID (VBS Enclave 가져오기 ID 바인딩 유틸리티)는 플랫폼 DLL에 대해 알려진 ID를 사용하여 VBS Enclave 내의 가져오기 테이블을 업데이트하는 Windows SDK의 도구입니다. 이렇게 하면 플랫폼 DLL 중 하나와 동일한 이름의 악성(서명된) DLL이 로드되지 않도록 방지하여 VBS Enclave의 보안을 향상시킵니다.
샘플 코드에서 이 작업은 빌드 후 이벤트로 자동으로 수행됩니다.
참고 항목
플랫폼 DLL을 제외한 자체 기본이 아닌 DLL을 사용하지 않는 것이 좋습니다. 대신 Enclave DLL 자체 내에서 모든 코드를 유지합니다.
3단계: VBS Enclave DLL 서명
VBS enclave를 성공적으로 로드하려면 서명해야 합니다. Enclave의 서명에는 enclave 작성자에 대한 정보가 포함됩니다. Enclave에 대한 작성자 ID를 파생하는 데 사용됩니다. 프로덕션용으로 서명하기 전에 Enclave에 테스트 서명할 수 있습니다.
테스트 서명 – 로컬
각 enclave 서명 인증서에는 3개 이상의 EKU가 필요합니다.
코드 서명 EKU -
1.3.6.1.5.5.7.3.3
Enclave EKU -
1.3.6.1.4.1.311.76.57.1.15
작성자 EKU - EKU는 다음보다
999
큰 형식1.3.6.1.4.1.311.97.X.Y.Z
X
입니다.테스트를 위해 이 패턴과 일치하는 작성자 EKU를 사용하도록 선택할 수 있습니다. 프로덕션의 경우 프로덕션 인증서의 일부로 Author EKU가 제공됩니다(프로덕션 서명에 대한 자세한 내용은 아래 참조).
예:
1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346
Enclave DLL을 개발하는 동안 서명하려면 테스트 서명을 사용하도록 설정합니다. 테스트 서명을 사용하도록 설정하면 이러한 세 가지 EKU가 포함된 인증서를 만들고 해당 인증서로 enclave에 서명할 수 있습니다. New-SelfSignedCertificate cmdlet을 사용하여 인증서를 만들 수 있습니다. Enclave DLL은 페이지 해시 서명이어야 합니다.
참고 항목
인증서가 있으면 빌드 후 이벤트에서 서명 프로세스를 자동화할 수 있습니다.
New-SelfSignedCertificate -CertStoreLocation Cert:\\CurrentUser\\My -DnsName "MyTestEnclaveCert" -KeyUsage DigitalSignature -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -TextExtension "2.5.29.37={text}1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.76.57.1.15,1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346"
signtool sign /ph /fd SHA256 /n "MyTestEnclaveCert" vbsenclave.dll
Enclave DLL에 서명하면 이제 테스트 서명을 사용하도록 설정된 환경에서 로드할 수 있습니다.
프로덕션 서명 – 신뢰할 수 있는 서명(이전의 Azure 코드 서명)
Enclave에 대한 프로덕션 서명은 신뢰할 수 있는 서명의 VBS Enclave 인증서 프로필을 통해 제공됩니다. 신뢰할 수 있는 서명을 사용하는 방법에 대한 자세한 내용은 설명서를 참조하세요.
신뢰할 수 있는 서명을 사용하면 명령줄에서 enclave에 서명할 수도 있습니다. Visual Studio에서 enclave를 빌드할 때 실행 준비가 완료된 서명된 enclave를 출력합니다.
4단계: VBS Enclave 디버깅
일반적으로 enclave의 메모리는 디버거에서 숨겨지고 VTL0에서 보호됩니다. 그러나 VBS Enclave DLL을 디버그하려는 경우 개발 중에 디버깅되도록 빌드할 수 있습니다. Enclave는 VTL1 사용자 모드 프로세스이므로 사용자 모드 디버거를 사용하여 디버그할 수 있습니다.
enclave를 디버깅할 수 있도록 하려면 다음을 수행합니다.
- enclave DLL 이미지 구성은 디버깅을 허용해야 합니다. 이 작업은 IMAGE_ENCLAVE_CONFIG IMAGE_ENCLAVE_POLICY_DEBUGGABLE 플래그를 설정하여 수행됩니다.
- Enclave를 만드는 동안 디버깅을 허용해야 합니다. 이 작업은 CreateEnclave 호출에 전달된 ENCLAVE_CREATE_VBS_INFO 구조체에서 ENCLAVE_VBS_FLAG_DEBUG 플래그를 설정하여 수행됩니다.
Enclave를 디버그하려면:
- enclave 호스트 프로세스에 사용자 모드 디버거를 연결합니다.
- 호스트 프로세스가 메모리에 enclave 이미지를 로드한 후 enclave 기호를 다시 로드합니다.
- enclave 내의 함수에 중단점을 설정합니다. 이 디버거는 enclave 호출에서 디버거를 중단합니다.
CreateEnclave, InitializeEnclave 등에 대한 사용자 모드 중단점을 중단하여 해당 코드를 한 단계 더 실행할 수도 있습니다ntdll.dll
.
참고 항목
프로덕션 환경에서는 디버깅할 수 있는 enclave를 사용하지 마세요.
이제 첫 번째 VBS Enclave를 빌드하고 배포할 수 있습니다. 질문이 있는 경우 Windows 개발자 지원에 문의하세요.