티스토리 뷰
728x90
WinTrust API는 Windows 운영 체제에서 디지털 서명을 검증하고 파일 및 기타 객체의 신뢰성을 확인하는 데 사용됩니다. 이를 이해하기 쉽게 다이어그램으로 나타내 보겠습니다.
다음은 WinTrust API의 주요 구성 요소와 흐름을 설명하는 다이어그램입니다.
- 요청자(Requestor): 신뢰성을 확인하고자 하는 애플리케이션 또는 서비스.
- WinTrust API: 요청을 받아 디지털 서명을 검증하고 신뢰성을 평가하는 API.
- 정책(Policy): 신뢰성 확인에 사용되는 기준 및 규칙 집합.
- 신뢰 공급자(Trust Provider): 인증서와 서명을 검증하는 역할을 하는 엔티티.
- 결과(Result): 파일 또는 객체의 신뢰성에 대한 검증 결과.
[ 요청자 ] --> [ WinTrust API ] --> [ 정책 ]
|
v
[ 신뢰 공급자 ]
|
v
[ 결과 ]
- 요청자:
- 애플리케이션이 WinTrust API에 파일 또는 객체의 신뢰성 검증을 요청합니다.
- WinTrust API:
- 요청을 수신하고 검증 프로세스를 시작합니다.
- 정책:
- API는 지정된 정책을 사용하여 파일 또는 객체의 디지털 서명을 검토합니다.
- 신뢰 공급자:
- API는 신뢰 공급자를 호출하여 서명 및 인증서를 검증합니다.
- 결과:
- 검증 결과를 요청자에게 반환합니다(성공, 실패, 경고 등).
다음은 Windows OS에서 코드 서명 검증을 하는 CODE(C/C++) 입니다.
#pragma once
#include <windows.h>
#include <wintrust.h>
#include <softpub.h>
#include <wincrypt.h>
#include <iostream>
#pragma comment(lib,"wintrust")
class cVerifyCodeSign
{
DECLARE_NO_SELF_CLASS( nxcVerifyCodeSign );
public:
static bool IsVeirfyCodeSigned( const std::wstring& _ssFilePathName )
{
WINTRUST_FILE_INFO FileData;
memset( &FileData, 0, sizeof( FileData ) );
FileData.cbStruct = sizeof( WINTRUST_FILE_INFO );
FileData.pcwszFilePath = _ssFilePathName.c_str();
GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA WinTrustData;
memset( &WinTrustData, 0, sizeof( WinTrustData ) );
WinTrustData.cbStruct = sizeof( WinTrustData );
WinTrustData.pPolicyCallbackData = NULL;
WinTrustData.pSIPClientData = NULL;
WinTrustData.dwUIChoice = WTD_UI_NONE;
WinTrustData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; // 체인 전체의 폐지 상태를 검사합니다.
WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
WinTrustData.hWVTStateData = NULL;
WinTrustData.pwszURLReference = NULL;
WinTrustData.dwProvFlags = WTD_SAFER_FLAG | WTD_USE_DEFAULT_OSVER_CHECK; // OS 버전 체크를 기본 설정으로 사용합니다.
WinTrustData.dwUIContext = WTD_UICONTEXT_EXECUTE;
WinTrustData.pFile = &FileData;
LONG status = WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData );
WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE;
WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData );
return status == ERROR_SUCCESS;
}
static std::wstring GetSignerName( const std::wstring& _ssFilePathName )
{
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PCCERT_CONTEXT pCertContext = NULL;
std::wstring ssSignerNameW = L"Unknown";
DWORD dwEncoding= 0x00, dwContentType = 0x00, dwFormatType = 0x00;
if( !CryptQueryObject( CERT_QUERY_OBJECT_FILE, _ssFilePathName.c_str(), CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0,
&dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, (const void**) & pCertContext) )
{
return ssSignerNameW;
}
DWORD dwSignerInfo;
PCMSG_SIGNER_INFO pSignerInfo;
if( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo ) )
{
CryptMsgClose( hMsg );
CertCloseStore( hStore, 0 );
return ssSignerNameW;
}
pSignerInfo = (PCMSG_SIGNER_INFO)malloc( dwSignerInfo );
if( !CryptMsgGetParam( hMsg, CMSG_SIGNER_INFO_PARAM, 0, pSignerInfo, &dwSignerInfo ) )
{
free( pSignerInfo );
CryptMsgClose( hMsg );
CertCloseStore( hStore, 0 );
return ssSignerNameW;
}
CERT_INFO CertInfo;
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
pCertContext = CertFindCertificateInStore( hStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, &CertInfo, NULL );
if( pCertContext )
{
DWORD dwData;
dwData = CertGetNameStringW( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0 );
wchar_t* nameBuffer = new wchar_t[dwData];
if( CertGetNameStringW( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, nameBuffer, dwData ) ) {
ssSignerNameW = nameBuffer;
}
delete[] nameBuffer;
}
free( pSignerInfo );
CryptMsgClose( hMsg );
CertCloseStore( hStore, 0 );
if( pCertContext )
{
CertFreeCertificateContext( pCertContext );
}
return ssSignerNameW;
}
};
사용 방법 입니다.
int Test()
{
std::wstring path = L"C:\\Path\\To\\YourSignedFile.exe";
if( cVerifyCodeSign::IsVeirfyCodeSigned( path ) ) {
std::wcout << L"The file is digitally signed." << std::endl;
std::wstring signerName = cVerifyCodeSign::GetSignerName( path );
std::wcout << L"Signer: " << signerName << std::endl;
}
else
{
std::wcout << L"The file is not digitally signed or the signature could not be verified." << std::endl;
}
return 0;
}
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- C
- DLL
- 제주도
- Build
- 서귀포블루버블
- CMake
- script
- C++
- 윈도우
- C#
- C# 고급 기술
- 블루버블다이빙팀
- 패턴
- C#.NET
- 성산블루버블
- 서귀포
- 티스토리챌린지
- 암호화
- 블루버블
- 울릉도
- 스쿠버 다이빙
- 블루버블다이브팀
- 현포다이브
- 스쿠버다이빙
- Linux
- PowerShell
- OpenSource
- 외돌개
- ip
- Windows
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함
250x250