验证文件数字签名

转载 2011年11月30日 16:51:11

工作中碰到需要判断一个PE文件是否是所确认的文件,而不是被替换过的。直接判断文件名的话有些不保险,别人只要修改下文件名,就可以以假乱真。

因而需要判断额外的信息;由于文件有数字签名,判断数字签名因而是一个比较好的方法,但是如果只是判断数字签名是否有效也不够,别人只要用自己的证书重新签名就可以了,所以需要判断证书签名者信息。

验证文件数字签名是否有效可以使用函数 WinVerifyTrust

取得文件数字签名证书信息需要使用函数 CryptQueryObject

下面是一段从网上搜到的获得文件数字签名证书信息的代码:

1 #include <windows.h>
  2 #include <wincrypt.h>
  3 #include <wintrust.h>
  4 #include <stdio.h>
  5 #include <tchar.h>
  6  #pragma comment(lib, "crypt32.lib")
  7  #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
  8 typedef struct {
  9     LPWSTR lpszProgramName;
 10     LPWSTR lpszPublisherLink;
 11     LPWSTR lpszMoreInfoLink;
 12 } SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;
 13 BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
 14                              PSPROG_PUBLISHERINFO Info);
 15 BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);
 16 BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);
 17 BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo,
 18                             PCMSG_SIGNER_INFO *pCounterSignerInfo);
 19  int _tmain(int argc, TCHAR *argv[])
 20 {
 21     WCHAR szFileName[MAX_PATH];
 22     HCERTSTORE hStore = NULL;
 23     HCRYPTMSG hMsg = NULL;
 24     PCCERT_CONTEXT pCertContext = NULL;
 25     BOOL fResult;
 26     DWORD dwEncoding, dwContentType, dwFormatType;
 27     PCMSG_SIGNER_INFO pSignerInfo = NULL;
 28     PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
 29     DWORD dwSignerInfo;
 30     CERT_INFO CertInfo;
 31     SPROG_PUBLISHERINFO ProgPubInfo;
 32     SYSTEMTIME st;
 33     ZeroMemory(&ProgPubInfo, sizeof(ProgPubInfo));
 34     __try
 35     {
 36         if (argc != 2)
 37         {
 38             _tprintf(_T("Usage: SignedFileInfo <filename>\n"));
 39             return 0;
 40         }
 41 #ifdef UNICODE
 42         lstrcpynW(szFileName, argv[1], MAX_PATH);
 43  #else
 44         if (mbstowcs(szFileName, argv[1], MAX_PATH) == -1)
 45         {
 46             printf("Unable to convert to unicode.\n");
 47             __leave;
 48         }
 49  #endif
 50         // Get message handle and store handle from the signed file.
 51          fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
 52             szFileName,
 53             CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
 54             CERT_QUERY_FORMAT_FLAG_BINARY,
 55             0,
 56             &dwEncoding,
 57             &dwContentType,
 58             &dwFormatType,
 59             &hStore,
 60             &hMsg,
 61             NULL);
 62         if (!fResult)
 63         {
 64             _tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError());
 65             __leave;
 66         }
 67         // Get signer information size.
 68          fResult = CryptMsgGetParam(hMsg,
 69             CMSG_SIGNER_INFO_PARAM,
 70             0,
 71             NULL,
 72             &dwSignerInfo);
 73         if (!fResult)
 74         {
 75             _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
 76             __leave;
 77         }
 78         // Allocate memory for signer information.
 79          pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
 80         if (!pSignerInfo)
 81         {
 82             _tprintf(_T("Unable to allocate memory for Signer Info.\n"));
 83             __leave;
 84         }
 85         // Get Signer Information.
 86         fResult = CryptMsgGetParam(hMsg,
 87             CMSG_SIGNER_INFO_PARAM,
 88             0,
 89             (PVOID)pSignerInfo,
 90             &dwSignerInfo);
 91         if (!fResult)
 92         {
 93             _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());
 94             __leave;
 95         }
 96         // Get program name and publisher information from
 97         // signer info structure.
 98         if (GetProgAndPublisherInfo(pSignerInfo, &ProgPubInfo))
 99         {
100             if (ProgPubInfo.lpszProgramName != NULL)
101             {
102                 wprintf(L"Program Name : %s\n",
103                     ProgPubInfo.lpszProgramName);
104             }
105             if (ProgPubInfo.lpszPublisherLink != NULL)
106             {
107                 wprintf(L"Publisher Link : %s\n",
108                     ProgPubInfo.lpszPublisherLink);
109             }
110             if (ProgPubInfo.lpszMoreInfoLink != NULL)
111             {
112                 wprintf(L"MoreInfo Link : %s\n",
113                     ProgPubInfo.lpszMoreInfoLink);
114             }
115         }
116         _tprintf(_T("\n"));
117         // Search for the signer certificate in the temporary
118         // certificate store.
119         CertInfo.Issuer = pSignerInfo->Issuer;
120         CertInfo.SerialNumber = pSignerInfo->SerialNumber;
121         pCertContext = CertFindCertificateInStore(hStore,
122             ENCODING,
123             0,
124             CERT_FIND_SUBJECT_CERT,
125             (PVOID)&CertInfo,
126             NULL);
127         if (!pCertContext)
128         {
129             _tprintf(_T("CertFindCertificateInStore failed with %x\n"),
130                 GetLastError());
131             __leave;
132         }
133         // Print Signer certificate information.
134         _tprintf(_T("Signer Certificate:\n\n"));
135         PrintCertificateInfo(pCertContext);
136         _tprintf(_T("\n"));
137         // Get the timestamp certificate signerinfo structure.
138         if (GetTimeStampSignerInfo(pSignerInfo, &pCounterSignerInfo))
139         {
140             // Search for Timestamp certificate in the temporary
141             // certificate store.
142             CertInfo.Issuer = pCounterSignerInfo->Issuer;
143             CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber;
144             pCertContext = CertFindCertificateInStore(hStore,
145                 ENCODING,
146                 0,
147                 CERT_FIND_SUBJECT_CERT,
148                 (PVOID)&CertInfo,
149                 NULL);
150             if (!pCertContext)
151             {
152                 _tprintf(_T("CertFindCertificateInStore failed with %x\n"),
153                     GetLastError());
154                 __leave;
155             }
156             // Print timestamp certificate information.
157             _tprintf(_T("TimeStamp Certificate:\n\n"));
158             PrintCertificateInfo(pCertContext);
159             _tprintf(_T("\n"));
160             // Find Date of timestamp.
161             if (GetDateOfTimeStamp(pCounterSignerInfo, &st))
162             {
163                 _tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"),
164                     st.wMonth,
165                     st.wDay,
166                     st.wYear,
167                     st.wHour,
168                     st.wMinute);
169             }
170             _tprintf(_T("\n"));
171         }
172     }
173     __finally
174     {
175         // Clean up.
176         if (ProgPubInfo.lpszProgramName != NULL)
177             LocalFree(ProgPubInfo.lpszProgramName);
178         if (ProgPubInfo.lpszPublisherLink != NULL)
179             LocalFree(ProgPubInfo.lpszPublisherLink);
180         if (ProgPubInfo.lpszMoreInfoLink != NULL)
181             LocalFree(ProgPubInfo.lpszMoreInfoLink);
182         if (pSignerInfo != NULL) LocalFree(pSignerInfo);
183         if (pCounterSignerInfo != NULL) LocalFree(pCounterSignerInfo);
184         if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
185         if (hStore != NULL) CertCloseStore(hStore, 0);
186         if (hMsg != NULL) CryptMsgClose(hMsg);
187     }
188     return 0;
189 }
190 BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
191 {
192     BOOL fReturn = FALSE;
193     LPTSTR szName = NULL;
194     DWORD dwData;
195     __try
196     {
197         // Print Serial Number.
198         _tprintf(_T("Serial Number: "));
199         dwData = pCertContext->pCertInfo->SerialNumber.cbData;
200         for (DWORD n = 0; n < dwData; n++)
201         {
202             _tprintf(_T("%02x "),
203                 pCertContext->pCertInfo->SerialNumber.pbData[dwData - (n + 1)]);
204         }
205         _tprintf(_T("\n"));
206         // Get Issuer name size.
207         if (!(dwData = CertGetNameString(pCertContext,
208             CERT_NAME_SIMPLE_DISPLAY_TYPE,
209             CERT_NAME_ISSUER_FLAG,
210             NULL,
211             NULL,
212             0)))
213         {
214             _tprintf(_T("CertGetNameString failed.\n"));
215             __leave;
216         }
217         // Allocate memory for Issuer name.
218         szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
219         if (!szName)
220         {
221             _tprintf(_T("Unable to allocate memory for issuer name.\n"));
222             __leave;
223         }
224         // Get Issuer name.
225         if (!(CertGetNameString(pCertContext,
226             CERT_NAME_SIMPLE_DISPLAY_TYPE,
227             CERT_NAME_ISSUER_FLAG,
228             NULL,
229             szName,
230             dwData)))
231         {
232             _tprintf(_T("CertGetNameString failed.\n"));
233             __leave;
234         }
235         // print Issuer name.
236         _tprintf(_T("Issuer Name: %s\n"), szName);
237         LocalFree(szName);
238         szName = NULL;
239         // Get Subject name size.
240         if (!(dwData = CertGetNameString(pCertContext,
241             CERT_NAME_SIMPLE_DISPLAY_TYPE,
242             0,
243             NULL,
244             NULL,
245             0)))
246         {
247             _tprintf(_T("CertGetNameString failed.\n"));
248             __leave;
249         }
250         // Allocate memory for subject name.
251         szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));
252         if (!szName)
253         {
254             _tprintf(_T("Unable to allocate memory for subject name.\n"));
255             __leave;
256         }
257         // Get subject name.
258         if (!(CertGetNameString(pCertContext,
259             CERT_NAME_SIMPLE_DISPLAY_TYPE,
260             0,
261             NULL,
262             szName,
263             dwData)))
264         {
265             _tprintf(_T("CertGetNameString failed.\n"));
266             __leave;
267         }
268         // Print Subject Name.
269         _tprintf(_T("Subject Name: %s\n"), szName);
270         fReturn = TRUE;
271     }
272     __finally
273     {
274         if (szName != NULL) LocalFree(szName);
275     }
276     return fReturn;
277 }
278 LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
279 {
280     LPWSTR outputString = NULL;
281     outputString = (LPWSTR)LocalAlloc(LPTR,
282         (wcslen(inputString) + 1) * sizeof(WCHAR));
283     if (outputString != NULL)
284     {
285         lstrcpyW(outputString, inputString);
286     }
287     return outputString;
288 }
289 BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo,
290                              PSPROG_PUBLISHERINFO Info)
291 {
292     BOOL fReturn = FALSE;
293     PSPC_SP_OPUS_INFO OpusInfo = NULL;
294     DWORD dwData;
295     BOOL fResult;
296     __try
297     {
298         // Loop through authenticated attributes and find
299         // SPC_SP_OPUS_INFO_OBJID OID.
300         for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
301         {
302             if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID,
303                 pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
304             {
305                 // Get Size of SPC_SP_OPUS_INFO structure.
306                 fResult = CryptDecodeObject(ENCODING,
307                     SPC_SP_OPUS_INFO_OBJID,
308                     pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
309                     pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
310                     0,
311                     NULL,
312                     &dwData);
313                 if (!fResult)
314                 {
315                     _tprintf(_T("CryptDecodeObject failed with %x\n"),
316                         GetLastError());
317                     __leave;
318                 }
319                 // Allocate memory for SPC_SP_OPUS_INFO structure.
320                 OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData);
321                 if (!OpusInfo)
322                 {
323                     _tprintf(_T("Unable to allocate memory for Publisher Info.\n"));
324                     __leave;
325                 }
326                 // Decode and get SPC_SP_OPUS_INFO structure.
327                 fResult = CryptDecodeObject(ENCODING,
328                     SPC_SP_OPUS_INFO_OBJID,
329                     pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
330                     pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
331                     0,
332                     OpusInfo,
333                     &dwData);
334                 if (!fResult)
335                 {
336                     _tprintf(_T("CryptDecodeObject failed with %x\n"),
337                         GetLastError());
338                     __leave;
339                 }
340                 // Fill in Program Name if present.
341                 if (OpusInfo->pwszProgramName)
342                 {
343                     Info->lpszProgramName =
344                         AllocateAndCopyWideString(OpusInfo->pwszProgramName);
345                 }
346                 else
347                     Info->lpszProgramName = NULL;
348                 // Fill in Publisher Information if present.
349                 if (OpusInfo->pPublisherInfo)
350                 {
351                     switch (OpusInfo->pPublisherInfo->dwLinkChoice)
352                     {
353                     case SPC_URL_LINK_CHOICE:
354                         Info->lpszPublisherLink =
355                             AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);
356                         break;
357                     case SPC_FILE_LINK_CHOICE:
358                         Info->lpszPublisherLink =
359                             AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);
360                         break;
361                     default:
362                         Info->lpszPublisherLink = NULL;
363                         break;
364                     }
365                 }
366                 else
367                 {
368                     Info->lpszPublisherLink = NULL;
369                 }
370                 // Fill in More Info if present.
371                 if (OpusInfo->pMoreInfo)
372                 {
373                     switch (OpusInfo->pMoreInfo->dwLinkChoice)
374                     {
375                     case SPC_URL_LINK_CHOICE:
376                         Info->lpszMoreInfoLink =
377                             AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);
378                         break;
379                     case SPC_FILE_LINK_CHOICE:
380                         Info->lpszMoreInfoLink =
381                             AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);
382                         break;
383                     default:
384                         Info->lpszMoreInfoLink = NULL;
385                         break;
386                     }
387                 }
388                 else
389                 {
390                     Info->lpszMoreInfoLink = NULL;
391                 }
392                 fReturn = TRUE;
393                 break; // Break from for loop.
394             } // lstrcmp SPC_SP_OPUS_INFO_OBJID
395         } // for
396     }
397     __finally
398     {
399         if (OpusInfo != NULL) LocalFree(OpusInfo);
400     }
401     return fReturn;
402 }
403 BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st)
404 {
405     BOOL fResult;
406     FILETIME lft, ft;
407     DWORD dwData;
408     BOOL fReturn = FALSE;
409     // Loop through authenticated attributes and find
410     // szOID_RSA_signingTime OID.
411     for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
412     {
413         if (lstrcmpA(szOID_RSA_signingTime,
414             pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
415         {
416             // Decode and get FILETIME structure.
417             dwData = sizeof(ft);
418             fResult = CryptDecodeObject(ENCODING,
419                 szOID_RSA_signingTime,
420                 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
421                 pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
422                 0,
423                 (PVOID)&ft,
424                 &dwData);
425             if (!fResult)
426             {
427                 _tprintf(_T("CryptDecodeObject failed with %x\n"),
428                     GetLastError());
429                 break;
430             }
431             // Convert to local time.
432             FileTimeToLocalFileTime(&ft, &lft);
433             FileTimeToSystemTime(&lft, st);
434             fReturn = TRUE;
435             break; // Break from for loop.
436         } //lstrcmp szOID_RSA_signingTime
437     } // for
438     return fReturn;
439 }
440 BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo)
441 {
442     PCCERT_CONTEXT pCertContext = NULL;
443     BOOL fReturn = FALSE;
444     BOOL fResult;
445     DWORD dwSize;
446     __try
447     {
448         *pCounterSignerInfo = NULL;
449         // Loop through unathenticated attributes for
450         // szOID_RSA_counterSign OID.
451         for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++)
452         {
453             if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId,
454                 szOID_RSA_counterSign) == 0)
455             {
456                 // Get size of CMSG_SIGNER_INFO structure.
457                 fResult = CryptDecodeObject(ENCODING,
458                     PKCS7_SIGNER_INFO,
459                     pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,
460                     pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,
461                     0,
462                     NULL,
463                     &dwSize);
464                 if (!fResult)
465                 {
466                     _tprintf(_T("CryptDecodeObject failed with %x\n"),
467                         GetLastError());
468                     __leave;
469                 }
470                 // Allocate memory for CMSG_SIGNER_INFO.
471                 *pCounterSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);
472                 if (!*pCounterSignerInfo)
473                 {
474                     _tprintf(_T("Unable to allocate memory for timestamp info.\n"));
475                     __leave;
476                 }
477                 // Decode and get CMSG_SIGNER_INFO structure
478                 // for timestamp certificate.
479                 fResult = CryptDecodeObject(ENCODING,
480                     PKCS7_SIGNER_INFO,
481                     pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,
482                     pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,
483                     0,
484                     (PVOID)*pCounterSignerInfo,
485                     &dwSize);
486                 if (!fResult)
487                 {
488                     _tprintf(_T("CryptDecodeObject failed with %x\n"),
489                         GetLastError());
490                     __leave;
491                 }
492                 fReturn = TRUE;
493                 break; // Break from for loop.
494             }
495         }
496     }
497     __finally
498     {
499         // Clean up.
500         if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
501     }
502     return fReturn;
503 }


 

相关文章推荐

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

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

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

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

快速了解数字签名验证及加解密中的一些概念

名词解释对称加密通信双方使用同一个密钥( secret )加密解密密钥(Secret)对称加密中双方共同使用的密码非对称加密通信中的密钥是成对的:公钥A和私钥B。用A加密的密文只能用B解密,同样,用B...

获取数字证书信息

// FileSign.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include ...

CSP开发基础--CayptAPI函数库介绍

基本加密函数 基本加密函数为开发加密应用程序提供了足够灵活的空间。所有CSP的通讯都是通过这些函数。一个CSP是实现所有加密操作的独立模块。在每一个应用程序中至少需要提供一个CSP来完成所需的加密操...
  • liuhuiyi
  • liuhuiyi
  • 2012年07月26日 14:34
  • 11864

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

转自:http://jmchxy.blog.163.com/blog/static/746082322013121113818518/ 近期有网友在博客中留言,希望俺介绍散列值校验文件的知识。所以俺...
  • adazone
  • adazone
  • 2015年08月10日 20:17
  • 1968

验证exe文件数字签名

  • 2012年02月02日 17:09
  • 502KB
  • 下载

amd_xata.sys 无法验证此文件的数字签名

1. 问题描述不知道动了电脑哪个地方,今天开机的时候,忽然就变成了这样 找了半天解决方案,终于解决了,现在总结一下。2. 解决思路从文件名上看,应该是AMD显卡驱动文件损坏了。缺什么补...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:验证文件数字签名
举报原因:
原因补充:

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