您的位置:首页 > 其它

验证文件数字签名

2011-11-30 16:51 218 查看
工作中碰到需要判断一个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
.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
.rgValue[0].pbData,
309                     pSignerInfo->AuthAttrs.rgAttr
.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
.rgValue[0].pbData,
330                     pSignerInfo->AuthAttrs.rgAttr
.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
.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
.rgValue[0].pbData,
421                 pSignerInfo->AuthAttrs.rgAttr
.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
.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
.rgValue[0].pbData,
460                     pSignerInfo->UnauthAttrs.rgAttr
.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
.rgValue[0].pbData,
482                     pSignerInfo->UnauthAttrs.rgAttr
.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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: