怎么取文件的数字签名

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

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

// FileSign.cpp : 定义控制台应用程序的入口点。
//

#include “stdafx.h”
#include <windows.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib, “crypt32.lib”)

#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)

typedef struct {
LPWSTR lpszProgramName;//程序名
LPWSTR lpszPublisherLink;//发布者链接
LPWSTR lpszMoreInfoLink;//更多信息链接
} SPROG_PUBLISHERINFO, *PSPROG_PUBLISHERINFO;

BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_PUBLISHERINFO Info);
//获取时间戳日期
BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st);

//打印证书信息
BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext);

//获取签名信息的时间戳
BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo);

int _tmain(int argc, TCHAR *argv[])
{
WCHAR szFileName[MAX_PATH];
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PCCERT_CONTEXT pCertContext = NULL;
BOOL fResult;
DWORD dwEncoding, dwContentType, dwFormatType;
PCMSG_SIGNER_INFO pSignerInfo = NULL;
PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
DWORD dwSignerInfo;
CERT_INFO CertInfo;
SPROG_PUBLISHERINFO ProgPubInfo;
SYSTEMTIME st;
ZeroMemory(&ProgPubInfo, sizeof(ProgPubInfo));

__try  
{  
    if (argc != 2)  
    {  
        _tprintf(_T("Usage: SignedFileInfo <filename>\n"));  
        return 0;  
    }  

#ifdef UNICODE
lstrcpynW(szFileName, argv[1], MAX_PATH);
#else
if (mbstowcs(szFileName, argv[1], MAX_PATH) == -1)
{
printf(“Unable to convert to unicode.\n”);
__leave;
}
#endif

    // Get message handle and store handle from the signed file.  
    //查询签名信息  
    fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,  
        szFileName,  
        CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,  
        CERT_QUERY_FORMAT_FLAG_BINARY,  
        0,  
        &dwEncoding,  
        &dwContentType,  
        &dwFormatType,  
        &hStore,  
        &hMsg,  
        NULL);  
    if (!fResult)  
    {  
        _tprintf(_T("CryptQueryObject failed with %x\n"), GetLastError());  
        __leave;  
    }  

    // Get signer information size.  
    fResult = CryptMsgGetParam(
        hMsg,  
        CMSG_SIGNER_INFO_PARAM,  
        0,  
        NULL,  
        &dwSignerInfo);  
    if (!fResult)  
    {  
        _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());  
        __leave;  
    }  

    // Allocate memory for signer information.  
    pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);  
    if (!pSignerInfo)  
    {  
        _tprintf(_T("Unable to allocate memory for Signer Info.\n"));  
        __leave;  
    }  

    // Get Signer Information.  
    fResult = CryptMsgGetParam(
        hMsg,  
        CMSG_SIGNER_INFO_PARAM,  
        0,  
        (PVOID)pSignerInfo,  
        &dwSignerInfo);  
    if (!fResult)  
    {  
        _tprintf(_T("CryptMsgGetParam failed with %x\n"), GetLastError());  
        __leave;  
    }  

    // Get program name and publisher information from  
    // signer info structure.  
    //获取程序名和发布者信息  
    if (GetProgAndPublisherInfo(pSignerInfo, &ProgPubInfo))  
    {  
        if (ProgPubInfo.lpszProgramName != NULL)  
        {  
            wprintf(L"Program Name : %s\n",  
                ProgPubInfo.lpszProgramName);  
        }  
        if (ProgPubInfo.lpszPublisherLink != NULL)  
        {  
            wprintf(L"Publisher Link : %s\n",  
                ProgPubInfo.lpszPublisherLink);  
        }  
        if (ProgPubInfo.lpszMoreInfoLink != NULL)  
        {  
            wprintf(L"MoreInfo Link : %s\n",  
                ProgPubInfo.lpszMoreInfoLink);  
        }  
    }  
    _tprintf(_T("\n")); 

    // Search for the signer certificate in the temporary  
    // certificate store.  
    CertInfo.Issuer = pSignerInfo->Issuer;  
    CertInfo.SerialNumber = pSignerInfo->SerialNumber;  
    pCertContext = CertFindCertificateInStore(
        hStore,  
        ENCODING,  
        0,  
        CERT_FIND_SUBJECT_CERT,  
        (PVOID)&CertInfo,  
        NULL);  
    if (!pCertContext)  
    {  
        _tprintf(_T("CertFindCertificateInStore failed with %x\n"),  
            GetLastError());  
        __leave;  
    }  

    // Print Signer certificate information.  
    _tprintf(_T("Signer Certificate:\n\n"));  
    PrintCertificateInfo(pCertContext);  
    _tprintf(_T("\n"));  

    // Get the timestamp certificate signerinfo structure.  
    if (GetTimeStampSignerInfo(pSignerInfo, &pCounterSignerInfo))  
    {  
        // Search for Timestamp certificate in the temporary  
        // certificate store.  
        CertInfo.Issuer = pCounterSignerInfo->Issuer;  
        CertInfo.SerialNumber = pCounterSignerInfo->SerialNumber;  
        pCertContext = CertFindCertificateInStore(hStore,  
            ENCODING,  
            0,  
            CERT_FIND_SUBJECT_CERT,  
            (PVOID)&CertInfo,  
            NULL);  
        if (!pCertContext)  
        {  
            _tprintf(_T("CertFindCertificateInStore failed with %x\n"),  
                GetLastError());  
            __leave;  
        }  

        // Print timestamp certificate information.  
        _tprintf(_T("TimeStamp Certificate:\n\n"));  
        PrintCertificateInfo(pCertContext);  
        _tprintf(_T("\n"));  

        // Find Date of timestamp.  
        if (GetDateOfTimeStamp(pCounterSignerInfo, &st))  
        {  
            _tprintf(_T("Date of TimeStamp : %02d/%02d/%04d %02d:%02d\n"),  
                st.wMonth,  
                st.wDay,  
                st.wYear,  
                st.wHour,  
                st.wMinute);  
        }  
        _tprintf(_T("\n"));  
    }  
}  
__finally  
{  
    // Clean up.  
    if (ProgPubInfo.lpszProgramName != NULL)  
        LocalFree(ProgPubInfo.lpszProgramName);  
    if (ProgPubInfo.lpszPublisherLink != NULL)  
        LocalFree(ProgPubInfo.lpszPublisherLink);  
    if (ProgPubInfo.lpszMoreInfoLink != NULL)  
        LocalFree(ProgPubInfo.lpszMoreInfoLink);  
    if (pSignerInfo != NULL) LocalFree(pSignerInfo);  
    if (pCounterSignerInfo != NULL) LocalFree(pCounterSignerInfo);  
    if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);  
    if (hStore != NULL) CertCloseStore(hStore, 0);  
    if (hMsg != NULL) CryptMsgClose(hMsg);  
}  
return 0;  

}

BOOL PrintCertificateInfo(PCCERT_CONTEXT pCertContext)
{
BOOL fReturn = FALSE;
LPTSTR szName = NULL;
DWORD dwData;
__try
{
// Print Serial Number.
_tprintf(_T(“Serial Number: “));
dwData = pCertContext->pCertInfo->SerialNumber.cbData;
for (DWORD n = 0; n < dwData; n++)
{
_tprintf(_T(”%02x “),
pCertContext->pCertInfo->SerialNumber.pbData[dwData - (n + 1)]);
}
_tprintf(_T(”\n”));

    // Get Issuer name size.  
    if (!(dwData = CertGetNameString(pCertContext,  
        CERT_NAME_SIMPLE_DISPLAY_TYPE,  
        CERT_NAME_ISSUER_FLAG,  
        NULL,  
        NULL,  
        0)))  
    {  
        _tprintf(_T("CertGetNameString failed.\n"));  
        __leave;  
    }  

    // Allocate memory for Issuer name.  
    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));  
    if (!szName)  
    {  
        _tprintf(_T("Unable to allocate memory for issuer name.\n"));  
        __leave;  
    }  

    // Get Issuer name.  
    if (!(CertGetNameString(pCertContext,  
        CERT_NAME_SIMPLE_DISPLAY_TYPE,  
        CERT_NAME_ISSUER_FLAG,  
        NULL,  
        szName,  
        dwData)))  
    {  
        _tprintf(_T("CertGetNameString failed.\n"));  
        __leave;  
    }  

    // print Issuer name.  
    _tprintf(_T("Issuer Name: %s\n"), szName);  
    LocalFree(szName);  
    szName = NULL;  

    // Get Subject name size.  
    if (!(dwData = CertGetNameString(
        pCertContext, 
        CERT_NAME_SIMPLE_DISPLAY_TYPE,  
        0,  
        NULL,  
        NULL,  
        0)))  
    {  
        _tprintf(_T("CertGetNameString failed.\n"));  
        __leave;  
    }  

    // Allocate memory for subject name.  
    szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR));  
    if (!szName)  
    {  
        _tprintf(_T("Unable to allocate memory for subject name.\n"));  
        __leave;  
    }  

    // Get subject name.  
    if (!(CertGetNameString(pCertContext,  
        CERT_NAME_SIMPLE_DISPLAY_TYPE,  
        0,  
        NULL,  
        szName,  
        dwData)))  
    {  
        _tprintf(_T("CertGetNameString failed.\n"));  
        __leave;  
    }  

    // Print Subject Name.  
    _tprintf(_T("Subject Name: %s\n"), szName);  
    fReturn = TRUE;  
}  
__finally  
{  
    if (szName != NULL) LocalFree(szName);  
}  
return fReturn;  

}

LPWSTR AllocateAndCopyWideString(LPCWSTR inputString)
{
LPWSTR outputString = NULL;
outputString = (LPWSTR)LocalAlloc(LPTR, (wcslen(inputString) + 1) * sizeof(WCHAR));
if (outputString != NULL)
{
lstrcpyW(outputString, inputString);
}
return outputString;
}

BOOL GetProgAndPublisherInfo(PCMSG_SIGNER_INFO pSignerInfo, PSPROG_PUBLISHERINFO Info)
{
BOOL fReturn = FALSE;
PSPC_SP_OPUS_INFO OpusInfo = NULL;
DWORD dwData;
BOOL fResult;
__try
{
// Loop through authenticated attributes and find
// SPC_SP_OPUS_INFO_OBJID OID.
for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
{
if (lstrcmpA(SPC_SP_OPUS_INFO_OBJID,
pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
{
// Get Size of SPC_SP_OPUS_INFO structure.
fResult = CryptDecodeObject(ENCODING,
SPC_SP_OPUS_INFO_OBJID,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
0,
NULL,
&dwData);
if (!fResult)
{
_tprintf(_T(“CryptDecodeObject failed with %x\n”),
GetLastError());
__leave;
}

            // Allocate memory for SPC_SP_OPUS_INFO structure.  
            OpusInfo = (PSPC_SP_OPUS_INFO)LocalAlloc(LPTR, dwData);  
            if (!OpusInfo)  
            {  
                _tprintf(_T("Unable to allocate memory for Publisher Info.\n"));  
                __leave;  
            }  

            // Decode and get SPC_SP_OPUS_INFO structure.  
            fResult = CryptDecodeObject(ENCODING,  
                SPC_SP_OPUS_INFO_OBJID,  
                pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,  
                pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,  
                0,  
                OpusInfo,  
                &dwData);  
            if (!fResult)  
            {  
                _tprintf(_T("CryptDecodeObject failed with %x\n"),  
                    GetLastError());  
                __leave;  
            }  

            // Fill in Program Name if present.  
            if (OpusInfo->pwszProgramName)  
            {  
                Info->lpszProgramName =  
                    AllocateAndCopyWideString(OpusInfo->pwszProgramName);  
            }  
            else  
                Info->lpszProgramName = NULL; 

            // Fill in Publisher Information if present.  
            if (OpusInfo->pPublisherInfo)  
            {  
                switch (OpusInfo->pPublisherInfo->dwLinkChoice)  
                {  
                case SPC_URL_LINK_CHOICE:  
                    Info->lpszPublisherLink =  
                        AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszUrl);  
                    break;  
                case SPC_FILE_LINK_CHOICE:  
                    Info->lpszPublisherLink =  
                        AllocateAndCopyWideString(OpusInfo->pPublisherInfo->pwszFile);  
                    break;  
                default:  
                    Info->lpszPublisherLink = NULL;  
                    break;  
                }  
            }  
            else  
            {  
                Info->lpszPublisherLink = NULL;  
            }  

            // Fill in More Info if present.  
            if (OpusInfo->pMoreInfo)  
            {  
                switch (OpusInfo->pMoreInfo->dwLinkChoice)  
                {  
                case SPC_URL_LINK_CHOICE:  
                    Info->lpszMoreInfoLink =  
                        AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszUrl);  
                    break;  
                case SPC_FILE_LINK_CHOICE:  
                    Info->lpszMoreInfoLink =  
                        AllocateAndCopyWideString(OpusInfo->pMoreInfo->pwszFile);  
                    break;  
                default:  
                    Info->lpszMoreInfoLink = NULL;  
                    break;  
                }  
            }  
            else  
            {  
                Info->lpszMoreInfoLink = NULL;  
            }  

            fReturn = TRUE;  
            break; // Break from for loop.  
        } // lstrcmp SPC_SP_OPUS_INFO_OBJID  
    } // for  
}  
__finally  
{  
    if (OpusInfo != NULL) LocalFree(OpusInfo);  
}  
return fReturn;  

}

BOOL GetDateOfTimeStamp(PCMSG_SIGNER_INFO pSignerInfo, SYSTEMTIME *st)
{
BOOL fResult;
FILETIME lft, ft;
DWORD dwData;
BOOL fReturn = FALSE;
// Loop through authenticated attributes and find
// szOID_RSA_signingTime OID.
for (DWORD n = 0; n < pSignerInfo->AuthAttrs.cAttr; n++)
{
if (lstrcmpA(szOID_RSA_signingTime, pSignerInfo->AuthAttrs.rgAttr[n].pszObjId) == 0)
{
// Decode and get FILETIME structure.
dwData = sizeof(ft);
fResult = CryptDecodeObject(ENCODING,
szOID_RSA_signingTime,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,
0,
(PVOID)&ft,
&dwData);
if (!fResult)
{
_tprintf(_T(“CryptDecodeObject failed with %x\n”),
GetLastError());
break;
}

        // Convert to local time.  
        FileTimeToLocalFileTime(&ft, &lft);  
        FileTimeToSystemTime(&lft, st);  
        fReturn = TRUE;  
        break; // Break from for loop.  
    } //lstrcmp szOID_RSA_signingTime  
} // for  
return fReturn;  

}

BOOL GetTimeStampSignerInfo(PCMSG_SIGNER_INFO pSignerInfo, PCMSG_SIGNER_INFO *pCounterSignerInfo)
{
PCCERT_CONTEXT pCertContext = NULL;
BOOL fReturn = FALSE;
BOOL fResult;
DWORD dwSize;
__try
{
*pCounterSignerInfo = NULL;
// Loop through unathenticated attributes for
// szOID_RSA_counterSign OID.
for (DWORD n = 0; n < pSignerInfo->UnauthAttrs.cAttr; n++)
{
if (lstrcmpA(pSignerInfo->UnauthAttrs.rgAttr[n].pszObjId, szOID_RSA_counterSign) == 0)
{
// Get size of CMSG_SIGNER_INFO structure.
fResult = CryptDecodeObject(ENCODING,
PKCS7_SIGNER_INFO,
pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,
0,
NULL,
&dwSize);
if (!fResult)
{
_tprintf(_T(“CryptDecodeObject failed with %x\n”),
GetLastError());
__leave;
}

            // Allocate memory for CMSG_SIGNER_INFO.  
            *pCounterSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSize);  
            if (!*pCounterSignerInfo)  
            {  
                _tprintf(_T("Unable to allocate memory for timestamp info.\n"));  
                __leave;  
            }  

            // Decode and get CMSG_SIGNER_INFO structure  
            // for timestamp certificate.  
            fResult = CryptDecodeObject(ENCODING,  
                PKCS7_SIGNER_INFO,  
                pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].pbData,  
                pSignerInfo->UnauthAttrs.rgAttr[n].rgValue[0].cbData,  
                0,  
                (PVOID)*pCounterSignerInfo,  
                &dwSize);  
            if (!fResult)  
            {  
                _tprintf(_T("CryptDecodeObject failed with %x\n"),  
                    GetLastError());  
                __leave;  
            }  
            fReturn = TRUE;  
            break; // Break from for loop.  
        }  
    }  
}  
__finally  
{  
    // Clean up.  
    if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);  
}  
return fReturn;  

}

猜你喜欢

转载自blog.csdn.net/qq_43080331/article/details/83096192
今日推荐