zoukankan      html  css  js  c++  java
  • 判断PE文件的数字签名信息

    工作中碰到需要判断一个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 }
  • 相关阅读:
    红黑树-插入篇
    并查集
    Rabin-Karp【转载】
    KMP
    怎样花两月时间去应聘互联网公司 [转载]
    c++ 智能指针【转载】
    java序列化
    Web页面导出Excel表格
    基于jquery-UI的日期选择器
    Doc命令
  • 原文地址:https://www.cnblogs.com/Quincy/p/1775217.html
Copyright © 2011-2022 走看看