文件数字签名校验与信息获取

获取文件的catlog签名信息 直接嵌入在文件里的签名信息获取很简单,文件上右键属性-签名信息就可以看到 catlog签名稍微麻烦一下, 1.如果只是想验证签名,用WinVerifyTrust这样的high level api即可,示例代码如下(from sysinternal:https://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-fil 阅读详情

方法一、二兼容XP,三不兼容XP。


方法一:

/*
 * An example of file signature verification using WinTrust API
 * Derived from the sample vertrust.cpp in the Platform SDK
 *
 * Copyright (c) 2009 Mounir IDRASSI <mounir.idrassi@idrix.fr>. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 */

#ifndef UNICODE
#define UNICODE
#endif

#ifndef _UNICODE
#define _UNICODE
#endif

#define _WIN32_WINNT 0x0500
#define WINVER       0x0500

#include <windows.h>
#include <Softpub.h>
#include <Wincrypt.h>
#include <tchar.h>
#include <stdlib.h>

#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Wintrust.lib")

LPTSTR GetCertificateDescription(PCCERT_CONTEXT pCertCtx)
{
   DWORD dwStrType;
   DWORD dwCount;
   LPTSTR szSubjectRDN = NULL;

   dwStrType = CERT_X500_NAME_STR;
   dwCount = CertGetNameString(pCertCtx,
      CERT_NAME_RDN_TYPE,
      0,
      &dwStrType,
      NULL,
      0);
   if (dwCount)
   {
      szSubjectRDN = (LPTSTR) LocalAlloc(0, dwCount * sizeof(TCHAR));
      CertGetNameString(pCertCtx,
         CERT_NAME_RDN_TYPE,
         0,
         &dwStrType,
         szSubjectRDN,
         dwCount);
   }

   return szSubjectRDN;
}


int _tmain(int argc, _TCHAR* argv[])
{
   GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
   WINTRUST_FILE_INFO sWintrustFileInfo;
   WINTRUST_DATA      sWintrustData;
   HRESULT            hr;

   if (argc != 2)
   {
      _tprintf(_T("Usage: VerifyExeSignature file_name\n"));
      return -1;
   }

   memset((void*)&sWintrustFileInfo, 0x00, sizeof(WINTRUST_FILE_INFO));
   memset((void*)&sWintrustData, 0x00, sizeof(WINTRUST_DATA));

   sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
   sWintrustFileInfo.pcwszFilePath = argv[1];
   sWintrustFileInfo.hFile = NULL;

   sWintrustData.cbStruct            = sizeof(WINTRUST_DATA);
   sWintrustData.dwUIChoice          = WTD_UI_NONE;
   sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
   sWintrustData.dwUnionChoice       = WTD_CHOICE_FILE;
   sWintrustData.pFile               = &sWintrustFileInfo;
   sWintrustData.dwStateAction       = WTD_STATEACTION_VERIFY;

   hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

   if (TRUST_E_NOSIGNATURE == hr)
   {
      _tprintf(_T("No signature found on the file.\n"));
   }
   else if (TRUST_E_BAD_DIGEST == hr)
   {
      _tprintf(_T("The signature of the file is invalid\n"));
   }
   else if (TRUST_E_PROVIDER_UNKNOWN == hr)
   {
      _tprintf(_T("No trust provider on this machine can verify this type of files.\n"));
   }
   else if (S_OK != hr)
   {
      _tprintf(_T("WinVerifyTrust failed with error 0x%.8X\n"), hr);
   }
   else
   {
      _tprintf(_T("File signature is OK.\n"));

      // retreive the signer certificate and display its information
      CRYPT_PROVIDER_DATA const *psProvData     = NULL;
      CRYPT_PROVIDER_SGNR       *psProvSigner   = NULL;
      CRYPT_PROVIDER_CERT       *psProvCert     = NULL;
      FILETIME                   localFt;
      SYSTEMTIME                 sysTime;

      psProvData = WTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
      if (psProvData)
      {
         psProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0 , FALSE, 0);
         if (psProvSigner)
         {
            FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
            FileTimeToSystemTime(&localFt, &sysTime);

            _tprintf(_T("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth,sysTime.wYear, sysTime.wHour,sysTime.wMinute,sysTime.wSecond);

            psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0);
            if (psProvCert)
            {
               LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
               if (szCertDesc)
               {
                  _tprintf(_T("File Signer = %s\n"), szCertDesc);
                  LocalFree(szCertDesc);
               }
            }

            if (psProvSigner->csCounterSigners)
            {
               _tprintf(_T("\n"));
               // Timestamp information
               FileTimeToLocalFileTime(&psProvSigner->pasCounterSigners[0].sftVerifyAsOf, &localFt);
               FileTimeToSystemTime(&localFt, &sysTime);

               _tprintf(_T("Timestamp Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth,sysTime.wYear, sysTime.wHour,sysTime.wMinute,sysTime.wSecond);               
               psProvCert = WTHelperGetProvCertFromChain(&psProvSigner->pasCounterSigners[0], 0);
               if (psProvCert)
               {
                  LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                  if (szCertDesc)
                  {
                     _tprintf(_T("Timestamp Signer = %s\n"), szCertDesc);
                     LocalFree(szCertDesc);
                  }
               }
            }
         }
      }
   }
   
   sWintrustData.dwUIChoice = WTD_UI_NONE;
   sWintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
   WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

	return 0;
}




方法二:

#include <windows.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <mscat.h>
#include <wchar.h>

#pragma comment(lib, "wintrust")

BOOLEAN IsFileDigitallySigned(PWCHAR FilePath)
{
	//Author: AD, 2009
	PVOID Context;
	HANDLE FileHandle;
	DWORD HashSize = 0;
	PBYTE Buffer;
	PVOID CatalogContext;
	CATALOG_INFO InfoStruct;
	WINTRUST_DATA WintrustStructure;
	WINTRUST_CATALOG_INFO WintrustCatalogStructure;
	WINTRUST_FILE_INFO WintrustFileStructure;
	PWCHAR MemberTag;
	BOOLEAN ReturnFlag = FALSE;
	ULONG ReturnVal;
	GUID ActionGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;

	//Zero our structures.
	memset(&InfoStruct, 0, sizeof(CATALOG_INFO));
	InfoStruct.cbStruct = sizeof(CATALOG_INFO);
	memset(&WintrustCatalogStructure, 0, sizeof(WINTRUST_CATALOG_INFO));
	WintrustCatalogStructure.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
	memset(&WintrustFileStructure, 0, sizeof(WINTRUST_FILE_INFO));
	WintrustFileStructure.cbStruct = sizeof(WINTRUST_FILE_INFO);

	//Get a context for signature verification.
	if (!CryptCATAdminAcquireContext(&Context, NULL, 0))
	{
		return FALSE;
	}

	//Open file.
	FileHandle = CreateFileW(FilePath, GENERIC_READ, 7, NULL, OPEN_EXISTING, 0, NULL);
	if (INVALID_HANDLE_VALUE == FileHandle)
	{
		CryptCATAdminReleaseContext(Context, 0);
		return FALSE;
	}

	//Get the size we need for our hash.
	CryptCATAdminCalcHashFromFileHandle(FileHandle, &HashSize, NULL, 0);
	if (HashSize == 0)
	{
		//0-sized has means error!
		CryptCATAdminReleaseContext(Context, 0);
		CloseHandle(FileHandle);
		return FALSE;
	}

	//Allocate memory.
	Buffer = (PBYTE)calloc(HashSize, 1);

	//Actually calculate the hash
	if (!CryptCATAdminCalcHashFromFileHandle(FileHandle, &HashSize, Buffer, 0))
	{
		CryptCATAdminReleaseContext(Context, 0);
		free(Buffer);
		CloseHandle(FileHandle);
		return FALSE;
	}

	//Convert the hash to a string.
	MemberTag = (PWCHAR)calloc((HashSize * 2) + 1, sizeof(WCHAR));
	for (unsigned int i = 0; i < HashSize; i++)
	{
		swprintf(&MemberTag[i * 2],100, L"%02X", Buffer[i]);
	}

	//Get catalog for our context.
	CatalogContext = CryptCATAdminEnumCatalogFromHash(Context, Buffer, HashSize, 0, NULL);
	if (CatalogContext)
	{
		//If we couldn't get information
		if (!CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0))
		{
			//Release the context and set the context to null so it gets picked up below.
			CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);
			CatalogContext = NULL;
		}
	}

	//If we have a valid context, we got our info.  
	//Otherwise, we attempt to verify the internal signature.
	if (!CatalogContext)
	{
		WintrustFileStructure.cbStruct = sizeof(WINTRUST_FILE_INFO);
		WintrustFileStructure.pcwszFilePath = FilePath;
		WintrustFileStructure.hFile = NULL;
		WintrustFileStructure.pgKnownSubject = NULL;

		WintrustStructure.cbStruct = sizeof(WINTRUST_DATA);
		WintrustStructure.dwUnionChoice = WTD_CHOICE_FILE;
		WintrustStructure.pFile = &WintrustFileStructure;
		WintrustStructure.dwUIChoice = WTD_UI_NONE;
		WintrustStructure.fdwRevocationChecks = WTD_REVOKE_NONE;
		WintrustStructure.dwStateAction = WTD_STATEACTION_IGNORE;
		WintrustStructure.dwProvFlags = WTD_SAFER_FLAG;
		WintrustStructure.hWVTStateData = NULL;
		WintrustStructure.pwszURLReference = NULL;
	}
	else
	{
		//If we get here, we have catalog info!  Verify it.
		WintrustStructure.cbStruct = sizeof(WINTRUST_DATA);
		WintrustStructure.pPolicyCallbackData = 0;
		WintrustStructure.pSIPClientData = 0;
		WintrustStructure.dwUIChoice = WTD_UI_NONE;
		WintrustStructure.fdwRevocationChecks = WTD_REVOKE_NONE;
		WintrustStructure.dwUnionChoice = WTD_CHOICE_CATALOG;
		WintrustStructure.pCatalog = &WintrustCatalogStructure;
		WintrustStructure.dwStateAction = WTD_STATEACTION_VERIFY;
		WintrustStructure.hWVTStateData = NULL;
		WintrustStructure.pwszURLReference = NULL;
		WintrustStructure.dwProvFlags = 0;
		WintrustStructure.dwUIContext = WTD_UICONTEXT_EXECUTE;

		//Fill in catalog info structure.
		WintrustCatalogStructure.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
		WintrustCatalogStructure.dwCatalogVersion = 0;
		WintrustCatalogStructure.pcwszCatalogFilePath = InfoStruct.wszCatalogFile;
		WintrustCatalogStructure.pcwszMemberTag = MemberTag;
		WintrustCatalogStructure.pcwszMemberFilePath = FilePath;
		WintrustCatalogStructure.hMemberFile = NULL;
	}

	//Call our verification function.
	ReturnVal = WinVerifyTrust(0, &ActionGuid, &WintrustStructure);

	//Check return.
	ReturnFlag = SUCCEEDED(ReturnVal);

	//Free context.
	if (CatalogContext)
		CryptCATAdminReleaseCatalogContext(Context, CatalogContext, 0);

	//If we successfully verified, we need to free.
	if (ReturnFlag)
	{
		WintrustStructure.dwStateAction = WTD_STATEACTION_CLOSE;
		WinVerifyTrust(0, &ActionGuid, &WintrustStructure);
	}

	//Free memory.
	free(MemberTag);
	free(Buffer);
	CloseHandle(FileHandle);
	CryptCATAdminReleaseContext(Context, 0);

	return ReturnFlag;
}

int _tmain(int argc, _TCHAR* argv[])
{
	IsFileDigitallySigned(L"C:\\Windows\\System32\\svchost.exe");
}


方法三:

//验证数字签名有效性  xp下不兼容,为使xp下可用,暂不使用此代码
DWORD VerifyEmbeddedSignatures(_In_ PCWSTR FileName,
	_In_ HANDLE FileHandle,
	_In_ bool UseStrongSigPolicy);

DWORD VerifyCatalogSignature(_In_ HANDLE FileHandle,
	_In_ bool UseStrongSigPolicy);

BOOL VerifyFileSig(char *pFileName);


//
// 以下为验证数字签名有效性    xp下不兼容,为使xp下可用,暂不使用此代码
//

BOOL CheckFileTrust2(LPCWSTR lpFileName)	//传进来的必须是LPCWSTR型的,不可以是char*
{
	BOOL bRet = FALSE;
	WINTRUST_DATA wd = { 0 };
	WINTRUST_FILE_INFO wfi = { 0 };
	WINTRUST_CATALOG_INFO wci = { 0 };
	CATALOG_INFO ci = { 0 };
	HCATADMIN hCatAdmin = NULL;
	if (!CryptCATAdminAcquireContext(&hCatAdmin, NULL, 0))
	{
		return FALSE;
	}
	HANDLE hFile = CreateFileW(lpFileName, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, 0, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		CryptCATAdminReleaseContext(hCatAdmin, 0);
		return FALSE;
	}
	DWORD dwCnt = 100;
	BYTE byHash[100];
	CryptCATAdminCalcHashFromFileHandle(hFile, &dwCnt, byHash, 0);
	CloseHandle(hFile);
	LPWSTR pszMemberTag = new WCHAR[dwCnt * 2 + 1];
	for (DWORD dw = 0; dw < dwCnt; ++dw)
	{
		wsprintfW(&pszMemberTag[dw * 2], L"%02X", byHash[dw]);
	}
	HCATINFO hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin,
		byHash, dwCnt, 0, NULL);
	if (NULL == hCatInfo)
	{
		wfi.cbStruct = sizeof(WINTRUST_FILE_INFO);
		wfi.pcwszFilePath = lpFileName;
		wfi.hFile = NULL;
		wfi.pgKnownSubject = NULL;
		wd.cbStruct = sizeof(WINTRUST_DATA);
		wd.dwUnionChoice = WTD_CHOICE_FILE;
		wd.pFile = &wfi;
		wd.dwUIChoice = WTD_UI_NONE;
		wd.fdwRevocationChecks = WTD_REVOKE_NONE;
		wd.dwStateAction = WTD_STATEACTION_IGNORE;
		wd.dwProvFlags = WTD_SAFER_FLAG;
		wd.hWVTStateData = NULL;
		wd.pwszURLReference = NULL;
	}
	else
	{
		CryptCATCatalogInfoFromContext(hCatInfo, &ci, 0);
		wci.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
		wci.pcwszCatalogFilePath = ci.wszCatalogFile;
		wci.pcwszMemberFilePath = lpFileName;
		wci.pcwszMemberTag = pszMemberTag;
		wd.cbStruct = sizeof(WINTRUST_DATA);
		wd.dwUnionChoice = WTD_CHOICE_CATALOG;
		wd.pCatalog = &wci;
		wd.dwUIChoice = WTD_UI_NONE;
		wd.fdwRevocationChecks = WTD_STATEACTION_VERIFY;
		wd.dwProvFlags = 0;
		wd.hWVTStateData = NULL;
		wd.pwszURLReference = NULL;
	}
	GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2;
	HRESULT hr = WinVerifyTrust(NULL, &action, &wd);
	bRet = SUCCEEDED(hr);
	if (NULL != hCatInfo)
	{
		CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0);
	}
	CryptCATAdminReleaseContext(hCatAdmin, 0);
	delete[] pszMemberTag;
	return bRet;
}

//----------------------------------------------------------------------------
//
//  VerifyEmbeddedSignatures
//  Verifies all embedded signatures of a file
//
//----------------------------------------------------------------------------
DWORD VerifyEmbeddedSignatures(_In_ PCWSTR FileName,
	_In_ HANDLE FileHandle,
	_In_ bool UseStrongSigPolicy)
{
	DWORD Error = ERROR_SUCCESS;
	bool WintrustCalled = false;
	GUID GenericActionId = WINTRUST_ACTION_GENERIC_VERIFY_V2;
	WINTRUST_DATA WintrustData = {};
	WINTRUST_FILE_INFO FileInfo = {};
	WINTRUST_SIGNATURE_SETTINGS SignatureSettings = {};
	CERT_STRONG_SIGN_PARA StrongSigPolicy = {};

	// Setup data structures for calling WinVerifyTrust
	WintrustData.cbStruct = sizeof(WINTRUST_DATA);
	WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
	WintrustData.dwUIChoice = WTD_UI_NONE;
	WintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
	WintrustData.dwUnionChoice = WTD_CHOICE_FILE;

	FileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO_);
	FileInfo.hFile = FileHandle;
	FileInfo.pcwszFilePath = FileName;
	WintrustData.pFile = &FileInfo;

	//
	// First verify the primary signature (index 0) to determine how many secondary signatures
	// are present. We use WSS_VERIFY_SPECIFIC and dwIndex to do this, also setting 
	// WSS_GET_SECONDARY_SIG_COUNT to have the number of secondary signatures returned.
	//
	SignatureSettings.cbStruct = sizeof(WINTRUST_SIGNATURE_SETTINGS);
	SignatureSettings.dwFlags = WSS_GET_SECONDARY_SIG_COUNT | WSS_VERIFY_SPECIFIC;
	SignatureSettings.dwIndex = 0;
	WintrustData.pSignatureSettings = &SignatureSettings;

	if (UseStrongSigPolicy != false)
	{
		StrongSigPolicy.cbSize = sizeof(CERT_STRONG_SIGN_PARA);
		StrongSigPolicy.dwInfoChoice = CERT_STRONG_SIGN_OID_INFO_CHOICE;
		StrongSigPolicy.pszOID = szOID_CERT_STRONG_SIGN_OS_CURRENT;
		WintrustData.pSignatureSettings->pCryptoPolicy = &StrongSigPolicy;
	}

	wprintf(L"Verifying primary signature... ");
	Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
	WintrustCalled = true;
	if (Error != ERROR_SUCCESS)
	{
		goto Cleanup;
	}

	wprintf(L"Success!\n");

	wprintf(L"Found %d secondary signatures\n", WintrustData.pSignatureSettings->cSecondarySigs);

	// Now attempt to verify all secondary signatures that were found
	for (DWORD x = 1; x <= WintrustData.pSignatureSettings->cSecondarySigs; x++)
	{
		wprintf(L"Verify secondary signature at index %d... ", x);

		// Need to clear the previous state data from the last call to WinVerifyTrust
		WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
		Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
		if (Error != ERROR_SUCCESS)
		{
			//No need to call WinVerifyTrust again
			WintrustCalled = false;
			goto Cleanup;
		}

		WintrustData.hWVTStateData = NULL;

		// Caller must reset dwStateAction as it may have been changed during the last call
		WintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
		WintrustData.pSignatureSettings->dwIndex = x;
		Error = WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
		if (Error != ERROR_SUCCESS)
		{
			goto Cleanup;
		}

		wprintf(L"Success!\n");
	}

Cleanup:

	//
	// Caller must call WinVerifyTrust with WTD_STATEACTION_CLOSE to free memory
	// allocate by WinVerifyTrust
	//
	if (WintrustCalled != false)
	{
		WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
		WinVerifyTrust(NULL, &GenericActionId, &WintrustData);
	}

	return Error;
}


//----------------------------------------------------------------------------
//
//  VerifyCatalogSignature
//  Looks up a file by hash in the system catalogs. 
//
//----------------------------------------------------------------------------
DWORD VerifyCatalogSignature(_In_ HANDLE FileHandle,
	_In_ bool UseStrongSigPolicy)
{
	DWORD Error = ERROR_SUCCESS;
	bool Found = false;
	HCATADMIN CatAdminHandle = NULL;
	HCATINFO CatInfoHandle = NULL;
	DWORD HashLength = 0;
	PBYTE HashData = NULL;
	CERT_STRONG_SIGN_PARA SigningPolicy = {};

	if (UseStrongSigPolicy != false)
	{
		SigningPolicy.cbSize = sizeof(CERT_STRONG_SIGN_PARA);
		SigningPolicy.dwInfoChoice = CERT_STRONG_SIGN_OID_INFO_CHOICE;
		SigningPolicy.pszOID = szOID_CERT_STRONG_SIGN_OS_CURRENT;
		if (!CryptCATAdminAcquireContext2(
			&CatAdminHandle,
			NULL,
			BCRYPT_SHA256_ALGORITHM,
			&SigningPolicy,
			0))
		{
			Error = GetLastError();
			goto Cleanup;
		}
	}
	else
	{
		if (!CryptCATAdminAcquireContext2(
			&CatAdminHandle,
			NULL,
			BCRYPT_SHA256_ALGORITHM,
			NULL,
			0))
		{
			Error = GetLastError();
			goto Cleanup;
		}
	}

	// Get size of hash to be used
	if (!CryptCATAdminCalcHashFromFileHandle2(
		CatAdminHandle,
		FileHandle,
		&HashLength,
		NULL,
		NULL))
	{
		Error = GetLastError();
		goto Cleanup;
	}

	HashData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, HashLength);
	if (HashData == NULL)
	{
		Error = ERROR_OUTOFMEMORY;
		goto Cleanup;
	}

	// Generate hash for a give file
	if (!CryptCATAdminCalcHashFromFileHandle2(
		CatAdminHandle,
		FileHandle,
		&HashLength,
		HashData,
		NULL))
	{
		Error = GetLastError();
		goto Cleanup;
	}

	// Find the first catalog containing this hash
	CatInfoHandle = NULL;
	CatInfoHandle = CryptCATAdminEnumCatalogFromHash(
		CatAdminHandle,
		HashData,
		HashLength,
		0,
		&CatInfoHandle);

	while (CatInfoHandle != NULL)
	{
		CATALOG_INFO catalogInfo = {};
		catalogInfo.cbStruct = sizeof(catalogInfo);
		Found = true;

		if (!CryptCATCatalogInfoFromContext(
			CatInfoHandle,
			&catalogInfo,
			0))
		{
			Error = GetLastError();
			break;
		}

		wprintf(L"Hash was found in catalog %s\n\n", catalogInfo.wszCatalogFile);

		// Look for the next catalog containing the file's hash
		CatInfoHandle = CryptCATAdminEnumCatalogFromHash(
			CatAdminHandle,
			HashData,
			HashLength,
			0,
			&CatInfoHandle);
	}

	if (Found != true)
	{
		Error = S_FALSE;
		wprintf(L"Hash was not found in any catalogs.\n");
	}

Cleanup:
	if (CatAdminHandle != NULL)
	{
		if (CatInfoHandle != NULL)
		{
			CryptCATAdminReleaseCatalogContext(CatAdminHandle, CatInfoHandle, 0);
		}

		CryptCATAdminReleaseContext(CatAdminHandle, 0);
	}

	if (HashData != NULL)
	{
		HeapFree(GetProcessHeap(), 0, HashData);
	}

	return Error;
}

BOOL VerifyFileSig(char *pFileName)
{
	bool UseStrongSigPolicy = false;
	WCHAR FilePathW[MAX_PATH] = { 0 };	//把char型的路径转换成wchar,CheckFileTrust必须传入wchar
	if (str::MByteToWChar(pFileName, FilePathW, MAX_PATH))
	{
		if (CheckFileTrust2(FilePathW))
		{
			return TRUE;
		}

		HANDLE FileHandle = CreateFileW(FilePathW,
			GENERIC_READ,
			FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			0,
			NULL);
		if (FileHandle == INVALID_HANDLE_VALUE)
		{
			return FALSE;
		}

		HRESULT hr = VerifyCatalogSignature(FileHandle, UseStrongSigPolicy);
		if (SUCCEEDED(hr))
		{
			hr = VerifyEmbeddedSignatures(FilePathW, FileHandle, UseStrongSigPolicy);
			CloseHandle(FileHandle);
			return SUCCEEDED(hr);// ? FALSE : TRUE;
		}
		else
		{
			CloseHandle(FileHandle);
			return TRUE;
		}
	}

	return FALSE;
}



//int __cdecl wmain(_In_ unsigned int argc, _In_reads_(argc) PCWSTR wargv[])
//{
//	DWORD Error = ERROR_SUCCESS;
//	HANDLE FileHandle = INVALID_HANDLE_VALUE;
//	DWORD ArgStart = 1;
//	bool UseStrongSigPolicy = false;
//
//	if (argc < 3 || argc > 4)
//	{
//		PrintUsage(wargv[0]);
//		Error = ERROR_INVALID_PARAMETER;
//		goto Cleanup;
//	}
//
//	if (_wcsicmp(wargv[ArgStart], L"-p") == 0)
//	{
//		UseStrongSigPolicy = true;
//		ArgStart++;
//	}
//
//	if (ArgStart + 1 >= argc)
//	{
//		PrintUsage(wargv[0]);
//		Error = ERROR_INVALID_PARAMETER;
//		goto Cleanup;
//	}
//
//	if ((wcslen(wargv[ArgStart]) != 2) ||
//		((_wcsicmp(wargv[ArgStart], L"-c") != 0) &&
//			(_wcsicmp(wargv[ArgStart], L"-e") != 0)))
//	{
//		PrintUsage(wargv[0]);
//		Error = ERROR_INVALID_PARAMETER;
//		goto Cleanup;
//	}
//
//	FileHandle = CreateFileW(wargv[ArgStart + 1],
//		GENERIC_READ,
//		FILE_SHARE_READ,
//		NULL,
//		OPEN_EXISTING,
//		0,
//		NULL);
//	if (FileHandle == INVALID_HANDLE_VALUE)
//	{
//		Error = GetLastError();
//		PrintError(Error);
//		goto Cleanup;
//	}
//
//	if (_wcsicmp(wargv[ArgStart], L"-c") == 0)
//	{
//		Error = VerifyCatalogSignature(FileHandle, UseStrongSigPolicy);
//	}
//	else if (_wcsicmp(wargv[ArgStart], L"-e") == 0)
//	{
//		Error = VerifyEmbeddedSignatures(wargv[ArgStart + 1], FileHandle, UseStrongSigPolicy);
//	}
//	else
//	{
//		PrintUsage(wargv[0]);
//		Error = ERROR_INVALID_PARAMETER;
//	}
//
//Cleanup:
//	if (FileHandle != INVALID_HANDLE_VALUE)
//	{
//		CloseHandle(FileHandle);
//	}
//
//	return Error;
//}


Proe5.0 M280终极版安装包获取与验证指南:如何安全下载并确认文件完整性? 本文详细介绍了Proe5.0 M280终极版安装包的安全获取与验证全流程,包括如何从官方或可信第三方平台下载、文件完整性验证方法(哈希校验、数字签名验证等)以及安装过程中的安全防护策略。帮助用户避免恶意软件和文件损坏风险,确保软件安装成功并稳定运行。 阅读详情

相关推荐

可执行文件校验机制设计:CRC与数字签名实战

深入探讨可执行文件的完整性保护,结合CRC校验与数字签名技术,实现安全可靠的验证机制,有效防范恶意篡改,保障可执行文件在分发和运行中的安全性。

weixin_42451850的博客 342

安全获取与验证资源下载地址的实用指南

在数字化时代,安全下载资源是每个用户的必备技能。下载地址验证的核心原理包括HTTPS协议、域名认证和文件完整性校验,这些技术能有效防范恶意软件和网络钓鱼。通过哈希值比对和数字签名检查等工程实践,可以确保下载文件的真实性和完整性。常见的应用场景包括软件安装、开源项目获取和大文件传输。本文重点介绍从官方网站、GitHub等开源平台到专业下载站的多渠道获取方法,以及使用IDM、aria2等工具进行高效下载管理的技巧,帮助用户建立安全的下载工作流。

weixin_29323049的博客 344

计算机网络安全:信息摘要、数字签名、数字证书

计算机网络安全:信息摘要、数字签名、数字证书

天涯雨的博客 1468

对Windows 平台下PE文件数字签名的一些研究

Windows平台上PE文件的数字签名有两个作用:确保文件来自指定的发布者和文件被签名后没有被修改过。因此有些软件用数字签名来验证文件是否来自家厂商以及文件的完整性,安全软件也经常通过验证文件是否有数字签名来防误报。但是因为windows对于常用的数字签名验证API- WinVerifyTrust实现的问题,以及一些并不恰当的示例代码,很多地方在验证数字签名时存在卡慢或者安全性不高的问题。本文将介...

snowfoxmonitor的专栏 7776

PDF文件安全验证实战:5步法校验哈希值与数字签名防篡改

在信息安全领域,数据完整性验证和身份认证是保障数字资产可信的基石。其核心原理基于密码学技术,通过哈希算法为文件生成唯一的数字指纹,确保内容未被篡改;同时借助公钥基础设施和数字签名技术,验证文件发布者的真实身份。这些技术对于软件分发、电子合同、技术文档等场景具有重要价值,能有效防范中间人攻击和恶意代码植入。本文以PDF文件为例,详细解析了从计算SHA-256哈希值到验证CA签发链的完整流程,并提供了自动化校验脚本的实现思路,帮助开发者构建可靠的文件验证体系。

weixin_29324877的博客 315

Java信息安全实战项目:数字签名与加密解密

MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,它可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5算法可以被看作是文件的“指纹”,对于文件中的每一个字节,MD5都会计算出一个16字节的“指纹”。MD5的原理包括以下几个步骤:填充:首先将待散列的消息填充至长度满足64位的整数倍,填充位的最后一个字节包含原数据长度的低8位,其余填充位则为0。添加长度值。

weixin_35753291的博客 1078

获取windows下执行文件签名和证书信息

获取证书信息验证文件数字签名是否有效可以使用函数 WinVerifyTrust,可以用:取得文件数字签名证书信息需要使用函数 CryptQueryObject,再用CertFindCertificateInStore获取证书Cert也可以通过,WTHelperProvDataFromStateData WTHelperGetProvSignerFromChain WTHelperGetProvCe...

weixin_34232617的博客 6030

51单片机———UART串口通信

传统理解就是信息的传输与交换。单片机与单片机之间,单片机与电脑之间,以及单片机与各式各样的模块之间都可以进行通信。如果没有通信,那么单片机的功能仅仅局限于它本身,它没办法从其他设备获取有用信息,也无法将自己产生的信息告诉其他设备,这样子单片机与外围器件的合作就会收到限制,没办法完成更多的功能,就像一个没办法拓展业务的公司。:实现我们程序当中写的P0=0xFC,就是一次同时对8位进行信号的输出;习惯上,我们还称P0、P1、P2、P3为单片机的4组并行总线:实现低位先发 高位在后。

m0_74225397的博客 3295

C++获取数字证书的序列号

C++获取数字证书的序列号目录C获取数字证书的序列号 目录 举个证书序列号的栗子 以下是一个简单的例子 转载请声明本文作者为天空中一米阳光 我们需要准备一个二进制的证书实体 或是 CRL,给出的例子可以直接解析出证书的序列号,而不需要通过任何的第三方的接口例如:openssl 、CryptoAPI 通过看ASN.1 得知: INTEGER 为任意一个整数 该标记码为 0x02 a

天空中一米阳光的专栏 4051

VS2022离线环境下的NuGet包管理:从本地源到依赖项全解析

本文详细解析了在VS2022离线环境下如何高效管理NuGet包,包括搭建本地NuGet源的两种方案(本地文件夹源和私有NuGet服务器)、获取离线包的三大渠道以及依赖项处理的实战技巧。通过自动化脚本和依赖树分析工具,帮助开发者解决离线环境中的依赖项黑洞问题,提升开发效率。

5f4d3s2a1q的博客 1060

【COMSOL】修改内置物理场方程 模拟水沸腾的蒸汽泡运动

在COMSOL中通过弱贡献(weak contribution)节点,可以向任何内置模型方程中添加约束。这里,以模拟水沸腾的蒸汽泡运动为例,来讲一讲当我们研究的方程与模块方程不一样时,应该怎么增加新的贡献项。

u012161192的博客 9008

gpg 校验文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <div id="content" class= "content mod-cs-content text-content clearfix"> $ gpg ht

danssion的专栏 1132

用Multisim和74HC系列芯片,手把手教你搭建一个能“算数”的简易CPU模型

本文详细介绍了如何使用Multisim仿真软件和74HC系列芯片搭建一个简易CPU模型,重点解析了74HC194寄存器和74HC283加法器的核心功能与连接方法。通过分步图解和实战调试,帮助读者理解CPU工作原理,掌握数字电路设计的基本技能,适合计算机组成原理初学者和电子爱好者实践学习。

weixin_26843605的博客 139

程序签名自校验 ,防止程序被病毒注入

/*****************************************************/ /* 软件本身数字签名校验 /*参数: /* unsigned char* pubkeyTLV 公钥TLV数据 /* unsigned int uiPubKLen 数据长度 /*返回值: /* TRUE 签名正常,程序未被改动 /* FALSE 签名无效,程序被篡改 /************************

空持百千偈的博客 913

在 Kubernetes 上部署 Label Studio

Label Studio 是一款开源的数据标注工具,支持多种标注任务,如文本标注、图像标注、音频标注等。

啥都会一点 668

「0基础安装本地Hermes」本地部署Hermes|为Hermes装上UI图形界面

Hermes已经发布有一段时间了,不少小伙伴也装配上了这个Agent。相对于之前发布爆火的Openclaw,Hermes对于很多小白不是很友好,它没有属于自己的UI界面,只能在本地终端运行,前不久Github上有人发布自己的作品,让终端里的Hermes拥有属于自己的UI界面,EKKOLearnAI开发的Hermes UI界面项目为终端运行的Hermes提供了可视化操作方式,降低了使用门槛。该项目通过Web界面与本地Hermes Agent交互,实现更友好的操作体验。

qq_55438365的博客 1872

java加密解密——MD5算法

MD5算法普遍用于数字签名技术 数字签名技术:可以检测文件或其他应用的完整性,判断有无修改; 简单应用如下:假设通信的两端,一端为文件的发送者,而另一端为文件的接受者。发送端:发送者对所发送的文件调用相关的函数来生成该文件的摘要信息,然后将该摘要信息用其本人的私钥进行加密处理,将摘要信息的密码模式与该文件一起发送给接受者;接受端:这时接受者共得到两样东西,一个是所需要的文件,另一个是已加密摘要...

云计算? 99

基于Simulink建模仿真的滑模控制的磁悬浮轴承稳定控制仿真

磁悬浮轴承(Magnetic Bearing)利用电磁力来支撑和定位转子,无需机械接触,因此在高速旋转设备中具有广泛应用。滑模控制(Sliding Mode Control, SMC)是一种鲁棒性强的非线性控制方法,适用于磁悬浮轴承的精确控制。以下是基于Simulink的磁悬浮轴承滑模控制系统的详细设计与仿真步骤。通过上述步骤,设计并实现了基于 Simulink 和 Control System Toolbox 的磁悬浮轴承滑模控制系统。

MHD0815的博客 780

判断PE文件的数字签名信息

工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。 因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而是一个比较好的方法,但是如果只是判断数字签名是否有效也不够,别人只要用自己的证书重新签名就可以了,所以需要判断证书签名者信息。   验证文件数字签名是否有效可以使用函数 WinVerifyTrus

求索 2482

135、高通 ChromaTix 调优工具入门:参数含义、调优流程与效果对比

本文介绍了高通ChromaTix色彩调优工具的核心使用要点:1. ChromaTix是位于ISP管线中的色彩处理系统,核心任务是将原始色彩映射为符合人眼感知的"舒适"效果;2. 重点解析了饱和度、色调、亮度相关饱和度等关键参数的实际含义和调试陷阱;3. 分享了四步调优流程,强调需要基于多场景数据验证;4. 通过案例展示了参数调整带来的色彩改善效果;5. 总结了实用建议,包括保持单一变量调试、量化评估色差、关注极端场景表现等。文章指出ChromaTix调优是平衡不同场景需求的"妥协艺术",需要结合客观数据和主

sundong_81的博客 107

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

2.6 数字签名校验机制

摘要:数字签名校验是保障软件安全的核心机制,通过非对称加密和哈希算法验证PE文件的完整性与来源真实性。其流程包括签名生成(哈希计算、私钥加密)与校验(公钥解密、哈希比对),依赖证书链验证和系统级防护(如Windows加载器)。常见攻击包括结构篡改、证书窃取等,防御需结合静态检测工具(SigCheck)和动态防护(代码完整性)。密码合规需遵循国际/国密标准(如SHA-256/SM3),未来面临量子计算等挑战。该机制是多层级协同的信任工程,需平衡算法强度与运维可控性。

勤奋的码农 1032

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

扫盲文件完整性校验——关于散列值和数字签名

[转自外星人某大牛博客] 近期有网友在博客中留言,希望俺介绍散列值校验文件的知识。所以俺干脆写一篇“文件完整性校验”的扫盲教程。由于本文是扫盲性质,尽量不涉及太技术化的内容。 ★啥是“完整性校验”? 所谓的“完整性校验”,顾名思义,就是检查文件是否完整。那么,什么情况下会导致文件不完整捏?大概有如下几种情况。 1. 感染病毒   比方说你的系统中了病毒,病毒感染了某个软件安装包或者某个可执行程序。那么该文件的完整性就被破坏了。 2. 植入木马/后门   还有一种文件不完整的情况,是被别有用心的人植入木马或后

u014447716的博客 2544

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

获取文件数字签名证书信息

验证文件数字签名是否有效可以使用函数 WinVerifyTrust 取得文件数字签名证书信息需要使用函数 CryptQueryObject。 // FileSign.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include #include #include #prag

linuxsmallping的专栏 4501

checksum命令 linux_数字签名及 Checksum 校验和

数字签名及验签一般情况,为了证明文件或信件从源端通过网络传输到目的端未被人为篡改,通常采用数字签名的技术。通过如下简单几步实现数据签名及验签。发送方数字签名过程:发送者通过散列函数将带发送的数据加工成散列值;发送者用私钥对散列值进行加密生成一段数字签名;发送者将待发送数据、数字签名、存有公钥的证书一并发送给接受者。接受方验签过程:提取出接收到的明文数据,用散列函数加工成散列值;用从信任签名者证书中...

weixin_39923945的博客 1535

常用的数字签名,信息加密算法

数字签名,信息加密是前后端开发经常使用的技术。应用场景包括:用户登录,交易,信息通讯等。

m0_51527921的博客 1669
上一篇: 路由器刷openwrt琐碎记录
下一篇: ida调试安卓手机手机apk
a33445621
博客等级 码龄19年 85粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值