获取文件的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的签名信息?

在接入第三方功能时,经常要注册提交apk的签名信息sha1签名? 获取apk签名信息的步骤: 1)修改apk后缀名为zip,解压得到其中的META-INF文件夹; 2)把META-INF文件夹放到C盘...
  • chenrushui
  • chenrushui
  • 2016年05月06日 18:31
  • 3926

<Android APK签名验签>二:META-INF文件分析

http://www.chenglong.ren/2016/12/30/android%E4%B8%AD%E7%AD%BE%E5%90%8D%E5%8E%9F%E7%90%86%E5%92%8C%E5...
  • weixin_37219611
  • weixin_37219611
  • 2017年07月19日 10:29
  • 219

如何查看apk和签名文件的签名信息

1.通过apktool工具解压当前apk(比如:demo.apk),解压后,会生成CERT.RSA文件 **** apktool d demo.apk 备注:通过这种方式解压出来的Andr...
  • cao_chen
  • cao_chen
  • 2016年12月09日 16:22
  • 2608

获取App中的签名信息

可以获取到某个apk的签名信息,在你不确定你的apk是否安装你的签名进行打包时候,可以获取打包好的apk签名信息进行比较...
  • niuba123456
  • niuba123456
  • 2015年09月06日 18:06
  • 2099

Android 使用代码获取签名信息

在使用百度地图,微信分享等等第三方SDK的时候,都需要在对应的网站上注册应用信息,其中之一就是通过包名和签名生成一个MD5或者SHA1编码的字符串。 通常情况下,这些信息可以通过ADT工具或者k...
  • Hcwfc
  • Hcwfc
  • 2014年11月28日 00:23
  • 1658

Android获取应用自身相关签名信息

Signature.javaimport android.content.Context; import android.content.pm.PackageInfo; import android....
  • wellchang
  • wellchang
  • 2015年08月27日 11:57
  • 1598

Android 获取jks签名信息

在各大App市场审核上架的时候,都需要App的签名信息,在创建了jks文件之后,能够获取到jks对应的sha1 ,MD5等信息也是必须的,在AS的Teminal面板操作,输入keytool -expo...
  • GerryRun
  • GerryRun
  • 2017年11月01日 19:25
  • 200

如何获取签名.jks中的SHA1

一般我们使用第三方的API,都会需要生成一个key来识别,而生成这个key的依据一般情况下都是根据该APP的签名的shar1来定义的,如百度地图等。那么我们该如何获取呢? 首先 xxx.jks :准备...
  • z1353095373
  • z1353095373
  • 2016年10月12日 10:17
  • 4976

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

验证文件数字签名是否有效可以使用函数 WinVerifyTrust 取得文件数字签名证书信息需要使用函数 CryptQueryObject。// FileSign.cpp : 定义控制台应用程序的入...
  • earbao
  • earbao
  • 2014年03月28日 11:18
  • 8171

Android 根据包名,获取应用程序的签名

前言最近在做一键分享功能。集成微信分享时,需要获取应用程序的签名,微信开放平台也提供了相应的小工具(下载地址),帮助我们获得签名。坑就坑在,这个小工具直接把签名字符串写在了 TexView ,不开源,...
  • heshiweij
  • heshiweij
  • 2016年04月23日 18:17
  • 7960
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:获取文件的catlog签名信息
举报原因:
原因补充:

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