获取文件的catlog签名信息

原创 2017年01月03日 19:49:03

直接嵌入在文件里的签名信息获取很简单,文件上右键属性-签名信息就可以看到

catlog签名稍微麻烦一下,

1.如果只是想验证签名,用WinVerifyTrust这样的high level api即可,示例代码如下(from sysinternal:https://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-file_topic19247.html)

#include <windows.h>
#include <wincrypt.h>
#include <mscat.h>
#include <wintrust.h>
#include <SoftPub.h>

#pragma comment (lib, "wintrust")

BOOL CheckMSSignature111(LPCWSTR lpFileName)
{
	BOOL bRet = FALSE;
	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]);
	}

	WINTRUST_DATA wd = { 0 };
	WINTRUST_FILE_INFO wfi = { 0 };
	WINTRUST_CATALOG_INFO wci = { 0 };
	CATALOG_INFO ci = { 0 };
	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;
}

2.如果要获取详细的签名人名称等信息,从上面的代码里CryptCATAdminEnumCatalogFromHash返回的ci.wszCatalogFile;里得到catlog文件的全路径后,继续解析,示例代码如下,(from https://support.microsoft.com/en-us/kb/323809)(入参为catlog文件的全路径,如

C:\\windows\\system32\\CatRoot\\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\\Package_4_for_KB3046017~31bf3856ad364e35~amd64~~6.1.1.1.cat"


BOOL GetSignName(LPCWSTR lpszCatFile, CString& strSignName)
{	CString strFile = lpszCatFile;
	if (strFile.IsEmpty())
	{
		return FALSE;
	}
	BOOL fResult;
	DWORD dwEncoding, dwContentType, dwFormatType;
	HCERTSTORE hStore = NULL;
	HCRYPTMSG hMsg = NULL;

	//查询签名信息
	fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
		(LPVOID)strFile.GetBuffer(),
		CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
		CERT_QUERY_FORMAT_FLAG_BINARY,
		0,
		&dwEncoding,
		&dwContentType,
		&dwFormatType,
		&hStore,
		&hMsg,
		NULL);
	if (!fResult)
	{
		WRITE_LOG(_T("CryptQueryObject failed with %x\n"), GetLastError());
		return FALSE;
	}
	// Get signer information size.
	DWORD dwSignerInfo;
	fResult = CryptMsgGetParam(hMsg,
		CMSG_SIGNER_INFO_PARAM,
		0,
		NULL,
		&dwSignerInfo);
	if (!fResult)
	{
		WRITE_LOG(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
		return FALSE;
	}
	// Allocate memory for signer information.
	PCMSG_SIGNER_INFO pSignerInfo = NULL;
	pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
	if (!pSignerInfo)
	{
		WRITE_LOG(_T("Unable to allocate memory for Signer Info.\n"));
		return FALSE;
	}
	// Get Signer Information.
	fResult = CryptMsgGetParam(hMsg,
		CMSG_SIGNER_INFO_PARAM,
		0,
		(PVOID)pSignerInfo,
		&dwSignerInfo);
	if (!fResult)
	{
		WRITE_LOG(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
		return FALSE;
	}

	// Search for the signer certificate in the temporary
	// certificate store.
	CERT_INFO CertInfo;
	CertInfo.Issuer = pSignerInfo->Issuer;
	CertInfo.SerialNumber = pSignerInfo->SerialNumber;
	PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore,
		X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
		0,
		CERT_FIND_SUBJECT_CERT,
		(PVOID)&CertInfo,
		NULL);
	if (!pCertContext)
	{
		WRITE_LOG(_T("CertFindCertificateInStore failed with %x\n"),
			GetLastError());
		return FALSE;
	}
	LPTSTR szName = NULL;
	DWORD dwData;
	if (!(dwData = CertGetNameString(pCertContext,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		NULL,
		0)))
	{
		WRITE_LOG(_T("CertGetNameString failed.\n"));
		return FALSE;
	}
	// Allocate memory for subject name.
	szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
	if (!szName)
	{
		WRITE_LOG(_T("Unable to allocate memory for subject name.\n"));
		return FALSE;
	}
	// Get subject name.
	if (!(CertGetNameString(pCertContext,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		szName,
		dwData)))
	{
		WRITE_LOG(_T("CertGetNameString failed.\n"));
		return FALSE;
	}
	strSignName = szName;
	return TRUE;
}





相关文章推荐

获取APK文件的签名信息,反射实现

private String showUninstallAPKSignatures(String apkPath) { String PATH_PackageParser = "and...
  • jia635
  • jia635
  • 2014年07月25日 00:07
  • 439

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

验证文件数字签名是否有效可以使用函数 WinVerifyTrust 取得文件数字签名证书信息需要使用函数 CryptQueryObject。 // FileSign.cpp : 定义控制台...

android获取APK文件,及应用内部签名信息方法

1.获取APK的签名信息 private String showUninstallAPKSignatures(String apkPath) { String PATH_Pack...

android studio签名文件在哪?以及查看MD5和SHA1信息

1.签名文件在哪: C:\Users\Administrator\.android \debug.keystore2.怎样查看获取SHA1或者MD5: (1)打开命令窗口:进入c盘的.an...

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

工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。 因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而...
  • wzsy
  • wzsy
  • 2015年03月30日 11:15
  • 1095

获取App签名信息

  • 2015年09月14日 21:29
  • 379KB
  • 下载

PackageInfo方式获取App签名信息(含MD5)

概述: Android对每一个Apk文件都会进行签名,在Apk文件安装时,系统会对其签名信息进行比对,判断程序的完整性,从而决定该Apk文件是否可以安装,在一定程度上达到安全的目的。 如何获取Ap...

android获取未安装APK签名信息及MD5指纹

站在巨人的肩膀上写博客: http://blog.csdn.net/wulianghuan/article/details/18400581http://www.jb51.net/article/7...

Android获取apk签名信息(举例说明java反射调用方法步骤)

以获取apk签名信息为例,举例反射调用方法的流程: 附上android源码查看链接,对比源码了解如何使用反射调用 http://grepcode.com/project/repository.gr...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:获取文件的catlog签名信息
举报原因:
原因补充:

(最多只允许输入30个字)