2013-02-22 124 views
3

我已經搜索了一種從數字簽名的PE文件中檢索信息的方法。我需要發佈者,發佈者鏈接,發行者姓名和主題名稱。我需要winapi/c/C++代碼(函數),我需要一個快速方法,我不需要檢查簽名是否有效。如何檢索文件數字簽名信息?

+2

如果你在談論「驗證碼」,微軟解釋這個位置:http://support.microsoft.com/kb/323809 – 2013-02-22 18:00:51

+0

感謝......這工作就像魅力.. – user2099394 2013-02-27 12:38:37

+1

好,我添加了一個相應的答案,所以你可以將它標記爲答案,如果它可以爲你 – 2013-02-27 12:41:52

回答

3

這是我爲我的項目編寫的代碼,它將執行此操作。它返回一個類型爲NSIGINFO的結構中的細節。隨意使用它 - 沒有必要的歸屬,但如果您保留版權,我將不勝感激。

如果缺少任何功能(我必須從幾個不同的地方合併東西,所以我可能錯過了一些東西),請讓我知道,我會做出必要的調整。

讓我知道這是如何適用於你。祝你好運。

頭文件,NAuthenticode.h

// NAuthenticode.h: Functions for checking signatures in files 
// 
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <[email protected]> 

#ifndef B82FBB5B_C0F8_43A5_9A31_619BB690706C 
#define B82FBB5B_C0F8_43A5_9A31_619BB690706C 

#include <wintrust.h> 
#include <softpub.h> 
#include <imagehlp.h> 

struct NSIGINFO 
{ 
    LONG lValidationResult; 

    LPTSTR lpszPublisher; 
    LPTSTR lpszPublisherEmail; 
    LPTSTR lpszPublisherUrl; 
    LPTSTR lpszAuthority; 
    LPTSTR lpszFriendlyName; 
    LPTSTR lpszProgramName; 
    LPTSTR lpszPublisherLink; 
    LPTSTR lpszMoreInfoLink; 
    LPTSTR lpszSignature; 
    LPTSTR lpszSerial; 
    BOOL bHasSigTime; 
    SYSTEMTIME stSigTime; 
}; 

VOID NCertFreeSigInfo(NSIGINFO *pSigInfo); 

BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle = INVALID_HANDLE_VALUE); 

BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType, 
    DWORD dwFlags, LPTSTR *lpszNameString); 

BOOL NCheckFileCertificates(HANDLE hFile, 
    VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam); 

#endif 

實施,NAuthenticode.cpp

// NAuthenticode.cpp: Various routines related to validating file signatures 
// 
// Copyright (c) 2008-2012, Nikolaos D. Bougalis <[email protected]> 


#include "stdafx.h" 
#include "NAuthenticode.h" 

////////////////////////////////////////////////////////////////////////// 
#pragma comment(lib, "crypt32") 
#pragma comment(lib, "imagehlp") 
#pragma comment(lib, "wintrust") 

////////////////////////////////////////////////////////////////////////// 
#define SIG_ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING) 

////////////////////////////////////////////////////////////////////////// 
// Some utility functions 
LPVOID NHeapAlloc(SIZE_T dwBytes) 
{ 
    if(dwBytes == 0) 
     return NULL; 

    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes); 
} 

////////////////////////////////////////////////////////////////////////// 
LPVOID NHeapFree(LPVOID lpMem) 
{ 
    if(lpMem != NULL) 
     HeapFree(GetProcessHeap(), 0, lpMem); 

    return NULL; 
} 

////////////////////////////////////////////////////////////////////////// 
LPSTR NConvertW2A(LPCWSTR lpszString, int nLen, UINT nCodePage) 
{ 
    ASSERT(lpszString != NULL); 

    int ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, NULL, 0, NULL, NULL); 

    if(ret <= 0) 
     return NULL; 

    LPSTR lpszOutString = (LPSTR)NHeapAlloc((ret + 1) * sizeof(CHAR)); 

    if(lpszOutString == NULL) 
     return NULL; 

    ret = WideCharToMultiByte(nCodePage, 0, lpszString, nLen, lpszOutString, ret, NULL, NULL); 

    if(ret <= 0) 
     lpszOutString = (LPSTR)NHeapFree(lpszOutString); 

    return lpszOutString; 
} 

////////////////////////////////////////////////////////////////////////// 
LPWSTR NDupString(LPCWSTR lpszString, int nLen) 
{ 
    if(nLen == -1) 
     nLen = (int)wcslen(lpszString); 

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((2 + nLen) * sizeof(WCHAR)); 

    if((lpszOutString != NULL) && (nLen != 0)) 
     wcsncpy(lpszOutString, lpszString, nLen + 1); 

    return lpszOutString; 
} 

////////////////////////////////////////////////////////////////////////// 
LPTSTR NConvertW2T(LPCWSTR lpszString, int nLen, UINT nCodePage) 
{ 
    ASSERT(lpszString != NULL); 

#ifndef UNICODE 
    return (LPTSTR)NConvertW2A(lpszString, nLen, nCodePage); 
#else 
    return (LPTSTR)NDupString(lpszString, nLen); 
#endif 
} 

////////////////////////////////////////////////////////////////////////// 
LPWSTR NConvertA2W(LPCSTR lpszString, int nLen, UINT nCodePage) 
{ 
    ASSERT(lpszString != NULL); 

    int ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, NULL, 0); 

    if(ret <= 0) 
     return NULL; 

    LPWSTR lpszOutString = (LPWSTR)NHeapAlloc((ret + 1) * sizeof(WCHAR)); 

    if(lpszOutString == NULL) 
     return NULL; 

    ret = MultiByteToWideChar(nCodePage, 0, lpszString, nLen, lpszOutString, ret); 

    if(ret <= 0) 
     lpszOutString = (LPWSTR)NHeapFree(lpszOutString); 

    return lpszOutString; 
} 

////////////////////////////////////////////////////////////////////////// 
LPWSTR NConvertT2W(LPCTSTR lpszString, int nLen, UINT nCodePage) 
{ 
    ASSERT(lpszString != NULL); 

#ifndef UNICODE 
    return NConvertA2W((LPCSTR)lpszString, nLen, nCodePage); 
#else 
    return NDupString((LPWSTR)lpszString, nLen); 
#endif 
} 

////////////////////////////////////////////////////////////////////////// 
VOID NCertFreeSigInfo(NSIGINFO *pSigInfo) 
{ 
    if(pSigInfo == NULL) 
     return; 

    __try 
    { // Be extra careful 
     if(pSigInfo->lpszPublisher) 
      pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

     if(pSigInfo->lpszPublisherEmail) 
      pSigInfo->lpszPublisherEmail = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherEmail); 

     if(pSigInfo->lpszPublisherUrl) 
      pSigInfo->lpszPublisherUrl = (LPTSTR)NHeapFree(pSigInfo->lpszPublisherUrl); 

     if(pSigInfo->lpszAuthority) 
      pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority); 

     if(pSigInfo->lpszProgramName) 
      pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

     if(pSigInfo->lpszPublisherLink) 
      pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

     if(pSigInfo->lpszMoreInfoLink) 
      pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink); 

     if(pSigInfo->lpszSignature) 
      pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature); 

     if(pSigInfo->lpszSerial) 
      pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial); 
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) 
    { 
    } 
} 

////////////////////////////////////////////////////////////////////////// 
static BOOL NCertGetNameString(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, LPTSTR *lpszNameString) 
{ 
    if(pCertContext == NULL) 
     return FALSE; 

    DWORD dwData = CertGetNameString(pCertContext, dwType, 0, NULL, NULL, 0); 

    if(dwData == 0) 
     return FALSE; 

    *lpszNameString = (LPTSTR)NHeapAlloc((dwData + 1) * sizeof(TCHAR)); 

    if(*lpszNameString == NULL) 
     return FALSE; 

    dwData = CertGetNameString(pCertContext, dwType, dwFlags, NULL, *lpszNameString, dwData); 

    if(dwData == 0) 
    { 
     NHeapFree(*lpszNameString); 
     return FALSE; 
    } 

    return TRUE; 
} 

////////////////////////////////////////////////////////////////////////// 
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in_bcount(cbEncoded) const BYTE *pbEncoded, __in DWORD cbEncoded, 
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0) 
{ 
    if(((pBuffer == NULL) && (dwBuffer != 0)) || ((dwBuffer == 0) && (pBuffer != NULL))) 
    { // What? You're passing a NULL pointer an a non-zero size? You so crazy!!!! 
     ASSERT(FALSE); 
     SetLastError(ERROR_INVALID_PARAMETER); 
     return FALSE; 
    } 

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pbEncoded, cbEncoded, dwFlags, pBuffer, &dwBuffer); 
} 

////////////////////////////////////////////////////////////////////////// 
static BOOL NCryptDecodeObject(__in LPCSTR lpszObjectId, __in PCRYPT_ATTR_BLOB pObject, 
    __inout DWORD &dwBuffer, __out void *pBuffer = NULL, __in DWORD dwFlags = 0) 
{ 
    if((pObject == NULL) || ((dwBuffer == 0) && (pBuffer != NULL)) || ((dwBuffer != 0) && (pBuffer == NULL))) 
    { 
     SetLastError(ERROR_INVALID_PARAMETER); 
     return FALSE; 
    } 

    return CryptDecodeObject(SIG_ENCODING, lpszObjectId, pObject->pbData, pObject->cbData, dwFlags, pBuffer, &dwBuffer); 
} 

////////////////////////////////////////////////////////////////////////// 
static BOOL WGetSignTimestamp(PCRYPT_ATTRIBUTES pAttributes, SYSTEMTIME &stTime, LPCSTR lpszObjId) 
{ 
    if((pAttributes == NULL) || (pAttributes->cAttr == 0) || (lpszObjId == NULL) || (*lpszObjId == 0)) 
     return FALSE; 

    for(DWORD dwAttr = 0; dwAttr < pAttributes->cAttr; dwAttr++) 
    {   
     if(strcmp(lpszObjId, pAttributes->rgAttr[dwAttr].pszObjId) == 0) 
     {    
      DWORD dwSize = sizeof(FILETIME); 
      FILETIME ftCert; 

      if(NCryptDecodeObject(lpszObjId, &pAttributes->rgAttr[dwAttr].rgValue[0], dwSize, (PVOID)&ftCert)) 
      { 
       FILETIME ftLocal; 

       if(FileTimeToLocalFileTime(&ftCert, &ftLocal) && FileTimeToSystemTime(&ftLocal, &stTime)) 
        return TRUE; 
      } 
     } 
    } 

    return FALSE; 
} 

////////////////////////////////////////////////////////////////////////// 
static BOOL NVerifyFileSignatureWorker(LPWSTR lpszFileName, WINTRUST_DATA &wtData, NSIGINFO *pSigInfo) 
{ 
    if(pSigInfo != NULL) 
     memset(pSigInfo, 0, sizeof(NSIGINFO)); 

    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;  
    BOOL bVerified = FALSE; 

    LONG lRet = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &wtData); 

    if(lRet != 0) 
    { 
     if(pSigInfo != NULL) 
      pSigInfo->lValidationResult = lRet; 

     return FALSE; 
    } 

    if(pSigInfo == NULL) 
     return TRUE; 

    HCERTSTORE hStore = NULL; 
    HCRYPTMSG hMsg = NULL; 

    if(!CryptQueryObject(CERT_QUERY_OBJECT_FILE, lpszFileName, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, &hStore, &hMsg, NULL)) 
     return FALSE; 

    PCMSG_SIGNER_INFO pSignerInfo = NULL, pCounterSignerInfo = NULL; 
    DWORD dwSignerInfo = 0, dwCounterSignerInfo = 0; 

    if(CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo) && (dwSignerInfo != 0)) 
     pSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwSignerInfo); 

    if((pSignerInfo != NULL) && CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo)) 
    { 
     for(DWORD dwAttr = 0; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++) 
     { 
      if((strcmp(SPC_SP_OPUS_INFO_OBJID, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) != 0)) 
       continue; 

      PSPC_SP_OPUS_INFO pOpus = NULL; 
      DWORD dwData = 0; 

      if(NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData) && (dwData != 0)) 
       pOpus = (PSPC_SP_OPUS_INFO)NHeapAlloc(dwData); 

      if((pOpus != NULL) && NCryptDecodeObject(SPC_SP_OPUS_INFO_OBJID, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)pOpus)) 
      {  
       pSigInfo->lpszProgramName = NConvertW2T(pOpus->pwszProgramName); 

       if(pOpus->pPublisherInfo != NULL) 
       { 
        switch(pOpus->pPublisherInfo->dwLinkChoice) 
        { 
        case SPC_URL_LINK_CHOICE: 
         pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszUrl); 
         break; 

        case SPC_FILE_LINK_CHOICE: 
         pSigInfo->lpszPublisherLink = NConvertW2T(pOpus->pPublisherInfo->pwszFile); 
         break; 
        } 
       } 

       if(pOpus->pMoreInfo != NULL) 
       { 
        switch (pOpus->pMoreInfo->dwLinkChoice) 
        { 
        case SPC_URL_LINK_CHOICE: 
         pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszUrl); 
         break; 

        case SPC_FILE_LINK_CHOICE: 
         pSigInfo->lpszMoreInfoLink = NConvertW2T(pOpus->pMoreInfo->pwszFile); 
         break; 
        } 
       }          
      }  

      if(pOpus != NULL) 
       NHeapFree(pOpus); 

      break; 
     } 

     CERT_INFO ci; 

     ci.Issuer = pSignerInfo->Issuer; 
     ci.SerialNumber = pSignerInfo->SerialNumber; 

     PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore, SIG_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&ci, NULL); 

     if(pCertContext != NULL) 
     {  
      if(pCertContext->pCertInfo->SerialNumber.cbData != 0) 
      { 
       pSigInfo->lpszSerial = (LPTSTR)NHeapAlloc(((pCertContext->pCertInfo->SerialNumber.cbData * 2) + 1) * sizeof(TCHAR)); 

       if(pSigInfo->lpszSerial != NULL) 
       { 
        LPTSTR lpszPointer = pSigInfo->lpszSerial; 

        for(DWORD dwCount = pCertContext->pCertInfo->SerialNumber.cbData; dwCount != 0; dwCount--) 
         lpszPointer += _stprintf(lpszPointer, _T("%02X"), pCertContext->pCertInfo->SerialNumber.pbData[dwCount - 1]); 
       } 
      } 

      if(!NCertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszFriendlyName)) 
       pSigInfo->lpszFriendlyName = NULL; 

      if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, &pSigInfo->lpszAuthority)) 
       pSigInfo->lpszAuthority = NULL; 

      if(!NCertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, &pSigInfo->lpszPublisher)) 
       pSigInfo->lpszPublisher = NULL; 

      if(!NCertGetNameString(pCertContext, CERT_NAME_URL_TYPE, 0, &pSigInfo->lpszPublisherUrl)) 
       pSigInfo->lpszPublisherUrl = NULL; 

      if(!NCertGetNameString(pCertContext, CERT_NAME_EMAIL_TYPE, 0, &pSigInfo->lpszPublisherEmail)) 
       pSigInfo->lpszPublisherEmail = NULL; 

      CertFreeCertificateContext(pCertContext); 
     } 

     for(DWORD dwAttr = 0, dwData; dwAttr < pSignerInfo->AuthAttrs.cAttr; dwAttr++) 
     {   
      if((strcmp(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[dwAttr].pszObjId) == 0) && (pSignerInfo->AuthAttrs.rgAttr[dwAttr].cValue != 0)) 
      { 
       FILETIME ftCert; 

       dwData = sizeof(FILETIME); 

       if(NCryptDecodeObject(szOID_RSA_signingTime, &pSignerInfo->AuthAttrs.rgAttr[dwAttr].rgValue[0], dwData, (PVOID)&ftCert)) 
       { 
        FILETIME ftLocal; 

        if(!FileTimeToLocalFileTime(&ftCert, &ftLocal)) 
        { 
         if(!FileTimeToSystemTime(&ftLocal, &pSigInfo->stSigTime)) 
          memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME)); 
        }     
       } 
      }   
     } 

     for(DWORD dwAttr = 0; dwAttr < pSignerInfo->UnauthAttrs.cAttr; dwAttr++) 
     { 
      if(strcmp(pSignerInfo->UnauthAttrs.rgAttr[dwAttr].pszObjId, szOID_RSA_counterSign) == 0) 
      { 
       if(NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo) && (dwCounterSignerInfo != 0)) 
        pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapAlloc(dwCounterSignerInfo); 

       if((pCounterSignerInfo != NULL) && !NCryptDecodeObject(PKCS7_SIGNER_INFO, &pSignerInfo->UnauthAttrs.rgAttr[dwAttr].rgValue[0], dwCounterSignerInfo, pCounterSignerInfo)) 
        pCounterSignerInfo = (PCMSG_SIGNER_INFO)NHeapFree(pCounterSignerInfo); 

       break; 
      } 
     } 

     if(pCounterSignerInfo != NULL) 
     { 
      pSigInfo->bHasSigTime = WGetSignTimestamp(&pCounterSignerInfo->AuthAttrs, pSigInfo->stSigTime, szOID_RSA_signingTime); 

      if(!pSigInfo->bHasSigTime) 
       memset(&pSigInfo->stSigTime, 0, sizeof(SYSTEMTIME)); 
     } 
    } 

    if(pSignerInfo != NULL) 
     NHeapFree(pSignerInfo); 

    if(pCounterSignerInfo != NULL) 
     NHeapFree(pCounterSignerInfo); 

    if(hStore != NULL) 
     CertCloseStore(hStore, 0); 

    if(hMsg != NULL) 
     CryptMsgClose(hMsg); 

    return TRUE; 
} 

////////////////////////////////////////////////////////////////////////// 
BOOL NVerifyFileSignature(LPCTSTR lpszFileName, NSIGINFO *pSigInfo, HANDLE hHandle) 
{ 
    if(pSigInfo != NULL)  
     memset(pSigInfo, 0, sizeof(NSIGINFO)); 

    if(lpszFileName == NULL) 
     return FALSE; 

    if((lpszFileName[0] != 0) && (_tcsnicmp(lpszFileName, _T("\\??\\"), 4) == 0)) 
     lpszFileName += 4; 

    if(lpszFileName[0] == 0) 
     return FALSE; 

    LPWSTR lpwszFileName = NConvertT2W(lpszFileName); 

    if(lpwszFileName == NULL) 
     return FALSE; 

    BOOL bOK = FALSE; 

    __try 
    { // be very careful... 
     WINTRUST_FILE_INFO wtFileInfo; 
     memset(&wtFileInfo, 0, sizeof(WINTRUST_FILE_INFO)); 

     wtFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO); 
     wtFileInfo.pcwszFilePath = lpwszFileName; 

     if(hHandle != INVALID_HANDLE_VALUE) 
      wtFileInfo.hFile = hHandle; 

     WINTRUST_DATA wtData; 
     memset(&wtData, 0, sizeof(WINTRUST_DATA)); 
     wtData.cbStruct = sizeof(WINTRUST_DATA); 
     wtData.dwUIChoice = WTD_UI_NONE; 
     wtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; 
     wtData.dwUnionChoice = WTD_CHOICE_FILE; 
     wtData.pFile = &wtFileInfo; 

     if(NVerifyFileSignatureWorker(lpwszFileName, wtData, pSigInfo)) 
      bOK = TRUE; 
    } 
    __except(EXCEPTION_EXECUTE_HANDLER) 
    { 
     if(pSigInfo != NULL) 
     { 
      if(pSigInfo->lpszPublisher) 
       pSigInfo->lpszPublisher = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

      if(pSigInfo->lpszAuthority) 
       pSigInfo->lpszAuthority = (LPTSTR)NHeapFree(pSigInfo->lpszAuthority); 

      if(pSigInfo->lpszProgramName) 
       pSigInfo->lpszProgramName = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

      if(pSigInfo->lpszPublisherLink) 
       pSigInfo->lpszPublisherLink = (LPTSTR)NHeapFree(pSigInfo->lpszPublisher); 

      if(pSigInfo->lpszMoreInfoLink) 
       pSigInfo->lpszMoreInfoLink = (LPTSTR)NHeapFree(pSigInfo->lpszMoreInfoLink); 

      if(pSigInfo->lpszSignature) 
       pSigInfo->lpszSignature = (LPTSTR)NHeapFree(pSigInfo->lpszSignature); 

      if(pSigInfo->lpszSerial) 
       pSigInfo->lpszSerial = (LPTSTR)NHeapFree(pSigInfo->lpszSerial); 
     } 

     bOK = FALSE; 
    } 

    NHeapFree(lpwszFileName); 

    return bOK; 
} 

////////////////////////////////////////////////////////////////////////// 
BOOL NCheckFileCertificates(HANDLE hFile, VOID (*pCallback)(PCCERT_CONTEXT, LPVOID), PVOID pParam) 
{ 
    DWORD dwCerts = 0; 

    if(!ImageEnumerateCertificates(hFile, CERT_SECTION_TYPE_ANY, &dwCerts, NULL, 0)) 
     return FALSE; 

    for(DWORD dwCount = 0; dwCount < dwCerts; dwCount++) 
    { 
     WIN_CERTIFICATE wcHdr; 
     memset(&wcHdr, 0, sizeof(WIN_CERTIFICATE)); 
     wcHdr.dwLength = 0; 
     wcHdr.wRevision = WIN_CERT_REVISION_1_0; 

     if(!ImageGetCertificateHeader(hFile, dwCount, &wcHdr)) 
      return FALSE; 

     DWORD dwLen = sizeof(WIN_CERTIFICATE) + wcHdr.dwLength; 

     WIN_CERTIFICATE *pWinCert = (WIN_CERTIFICATE *)NHeapAlloc(dwLen); 

     if(pWinCert == NULL) 
      return FALSE; 

     if(!ImageGetCertificateData(hFile, dwCount, pWinCert, &dwLen)) 
     { // problem getting certificate, return failure 
      NHeapFree(pWinCert); 
      return FALSE; 
     } 

     // extract the PKCS7 signed data  
     CRYPT_VERIFY_MESSAGE_PARA cvmp; 
     memset(&cvmp, 0, sizeof(CRYPT_VERIFY_MESSAGE_PARA)); 
     cvmp.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA); 
     cvmp.dwMsgAndCertEncodingType = SIG_ENCODING; 

     PCCERT_CONTEXT pCertContext = NULL; 

     if(!CryptVerifyMessageSignature(&cvmp, dwCount, pWinCert->bCertificate, pWinCert->dwLength, NULL, NULL, &pCertContext)) 
     { 
      NHeapFree(pWinCert); 
      return FALSE; 
     } 

     // Now, pass this context on to our callback function (if any) 
     if(pCallback != NULL) 
      pCallback(pCertContext, pParam); 

     if(!CertFreeCertificateContext(pCertContext)) 
     { 
      NHeapFree(pWinCert); 
      return FALSE; 
     } 

     NHeapFree(pWinCert); 
    } 

    return TRUE; 
} 
+1

謝謝代碼,我沒有檢查它。我使用了微軟提供的代碼 – user2099394 2013-02-27 12:40:34

4

微軟提供了一個辦法做到這一點在此支持鏈接:How To Get Information from Authenticode Signed Executables

你可以使用WinVerifyTrust()API來驗證已簽署的Authenticode 可執行文件。

雖然簽名進行驗證,程序可能還需要做到以下 :

  • 確定簽署 可執行文件的證書的詳細信息。
  • 確定文件加蓋時間爲 的日期和時間。
  • 檢索與該文件關聯的URL鏈接。
  • 檢索時間戳證書。

本文演示如何使用 CryptQueryObject()API檢索從 驗證碼的詳細信息簽名的可執行。