C 验证已签名的PE文件
(很抱歉我的英语不好。)我的代码有一些问题。所以我会尽力解释我的问题。我有一个简单的带签名的exe文件(pkcs7)。我想验证此文件(没有internet连接)。我不想使用C 验证已签名的PE文件,c,winapi,certificate,portable-executable,wincrypt,C,Winapi,Certificate,Portable Executable,Wincrypt,(很抱歉我的英语不好。)我的代码有一些问题。所以我会尽力解释我的问题。我有一个简单的带签名的exe文件(pkcs7)。我想验证此文件(没有internet连接)。我不想使用WinVerifyTrust(),因为我想知道windows如何验证PE文件。我编写了一些代码,首先使用BLOB_数据(映射的pe文件)调用CryptQueryObject(),它运行良好。然后我可以获得证书信息:签名者、序列号等(使用CryptGetMsgParam()),它也可以正常工作;但是,当我用CertGetCert
WinVerifyTrust()
,因为我想知道windows如何验证PE文件。我编写了一些代码,首先使用BLOB_数据(映射的pe文件)调用CryptQueryObject()
,它运行良好。然后我可以获得证书信息:签名者、序列号等(使用CryptGetMsgParam()
),它也可以正常工作;但是,当我用CertGetCertificateChain()
验证它时,我得到了一个错误。那么,你能帮我解决这个问题吗?我认为我没有正确使用CertGetCertificateChain()
BOOL-bRet=FALSE;
DWORD dwMsgAndCertEncodingType=0;
DWORD dwContentType=0;
DWORD dwFormatType=0;
HCERTSTORE hStore=NULL;
HCRYPTMSG hMsg=NULL;
PCCERT_CONTEXT pCertContext=NULL;
CERT_BLOB BLOB_data={0};
//CERT_INFO CertInfo={0};
DWORD dwSignerInfo=0;
PCCERT\u CHAIN\u CONTEXT pChainContext=NULL;
PCMSG\u签名者\u信息pSignerInfo=NULL;
CERT_CHAIN_PARA ChainPara={0};
blob_data.pbData=pBuff;
blob_data.cbData=dwSize;
ChainPara.cbSize=sizeof(CERT\u CHAIN\u PARA);
bRet=CryptQueryObject(证书查询对象),
&blob_数据,
证书查询内容标志PKCS7签名嵌入,
证书\查询\格式\标志\二进制,
0,
无效的
&dwContentType,
无效的
&商店,
&hMsg,
&pCertContext);
if(bRet!=真)
{
printf(“错误CryptQueryObject\n”);
返回FALSE;
}
if(dwContentType!=证书\查询\内容\ PKCS7\签名\嵌入)
{
printf(“错误类型\n”);
返回FALSE;
}
cryptmsgetparam(hMsg、CMSG、签名者信息参数、0、NULL和dwSignerInfo);
pSignerInfo=HeapAlloc(GetProcessHeap(),HEAP\u ZERO\u内存,dwSignerInfo);
CryptmsgetParam(hMsg、CMSG、签名者信息参数、0、pSignerInfo和dwSignerInfo);
bRet=CertGetCertificateChain(NULL,(PCCERT\u上下文)PCCertContext,NULL,NULL,仅限证书链撤销检查缓存,
NULL,&pChainContext);
if(bRet!=真)
{
printf(“有错误\n”);
}
一个问题(虽然可能不是唯一的问题)是CertGetCertificateChain()
的第五个参数是NULL
?这应该指向一个CERT\u CHAIN\u PARA
结构。(您已经声明了一个,但似乎既没有初始化也没有使用它。)
我不知道您应该在这里输入什么数据,但下面是一个示例,它使用的代码取自一个实际(工作)程序(我自己制作的)来检查数字证书:
//...
CERT_CHAIN_PARA ChainPara; memset(&ChainPara, 0, sizeof(CERT_CHAIN_PARA));
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
ChainPara.RequestedUsage.Usage.cUsageIdentifier = 0;
//...
bRet = CertGetCertificateChain(NULL, (PCCERT_CONTEXT)pCertContext, NULL, NULL, &ChainPara,
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, NULL, &pChainContext);
//...
您可以查看CERT\u CHAIN\u PARA
的文档,了解您应该设置哪些实际数据/值
希望这有帮助!(请随时询问进一步的澄清和/或建议。)谢谢您的回复。是的,这可能是一个问题,但我实际上不知道如何使用它,因为没有好的信息和网络,我也没有看到任何好的例子(好的,评论现在移动到一个答案,有一些(希望有用)示例代码。嗨,Amfield,最好在你的问题中包含最基本的错误消息。现在你调用CertGetCertificateChain
,根据提示,出现了一个错误,要获取扩展错误信息,请调用GetLastError
。谢谢你,Adrian,但它没有帮助。我尝试了目录文件,可能会有所帮助