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

获取文件的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

CentOS7上装不了最新Chrome?别折腾依赖了,试试这个老版本安装法(附103.0.5060.24 beta下载地址)

本文提供了在CentOS7上安装兼容版Chrome的详细指南,解决了因GLIBC版本限制导致的最新版Chrome无法安装的问题。推荐使用Chrome 103.0.5060.24 beta版本,并附有下载地址和完整安装步骤,包括禁用自动更新和配套工具安装,确保系统稳定性和功能完整性。

weixin_29289821的博客 569

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

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

天空中一米阳光的专栏 4051

Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明

Utrust4701F与Utrust2700R读写器支持银河麒麟系统,广泛应用会员管理、支付管理等领域。本文将重点介绍Utrust4701F与Utrust2700R读写器在银河麒麟系统的安装及测试步骤说明。以上方法适用于主流国产操作系统,如 优麒麟(UbuntuKylin)/ 中标麒麟(NeoKylin) / UOS(统信操作系统)/ 中兴新支点 / 红旗 linux(redflag linux)/ 普华 Linux(I-soft OS) / 威科乐恩 Linux(WiOS)等

华翔天诚科技 1833

避坑指南:C# OpenCvSharp调用4K摄像头常见的5个问题及解决方案

本文针对C# OpenCvSharp调用4K高清摄像头时常见的五大难题,提供了详细的解决方案。内容涵盖分辨率设置失效、帧率卡顿、内存泄漏、硬件驱动兼容性以及性能优化实战,帮助开发者高效稳定地处理4K视频流,提升智能安防监控等项目的开发效率。

weixin_29268331的博客 423

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

CS231n+assignment2(一)

cs231n作业二详解+代码

qq_56551150的博客 2411

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

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

空持百千偈的博客 913

从零到一:Qt与PCL的跨平台开发环境搭建全攻略

本文详细介绍了从零开始搭建Qt与PCL跨平台开发环境的完整流程,涵盖Windows、Linux和macOS三大平台。重点解析了Qt5与Qt6版本选择、PCL库安装配置、VTK集成等关键技术要点,并提供跨平台CMake项目模板和常见问题解决方案,助力开发者快速构建三维点云处理应用。

weixin_29280657的博客 384

基于STM32设计的计算器(实现基本运算)

当前文章介绍的是STM32+LCD触摸屏设计的一个触摸计算器功能,实现基本的加减乘除,二进制转换显示等功能。LCD屏使用的是3.5寸带触摸屏的显示屏,方便操作屏幕,MCU采用STM32F103ZET6。

8817

java加密解密——MD5算法

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

云计算? 99

SAP S/4 HANA CO 成本模块实战指南

摘要:SAP S/4HANA CO(管理会计)模块是企业内部成本管理的核心工具。本文系统介绍了CO模块的组织结构(控制范围与会计科目表映射)、基础概念(计划值与预算值)以及6大子模块功能(成本要素、成本中心会计等)。重点解析了各子模块的应用场景与差异,包括成本归集、费用分摊、利润分析和产品成本控制,并对比了利润中心与成本中心、内部订单与销售订单的区别。通过事务代码示例和功能对比表,帮助用户快速掌握SAP CO模块的核心管理逻辑与实施要点。

金牌架构师 1125

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

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

求索 2482

B3640 T3 句子反转

要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。第一次做的时候0分,两个小时没做出来。仅一行,表示程序对句子的处理结果。仅一行,即需要反转的句子。

小前日记 366

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2.6 数字签名校验机制

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

勤奋的码农 1032

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

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

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

u014447716的博客 2544

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

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

验证文件数字签名是否有效可以使用函数 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、付费专栏及课程。

余额充值