读取数字签名方法

复制代码
#ifndef UNICODE
#define UNICODE
#endif

#ifndef _UNICODE
#define _UNICODE
#endif

#define _WIN32_WINNT 0x0500
#define WINVER       0x0500

#include <windows.h>
#include <Softpub.h>
#include <Wincrypt.h>
#include <tchar.h>
#include <stdlib.h>

#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Wintrust.lib")

LPTSTR GetCertificateDescription(PCCERT_CONTEXT pCertCtx)
{
    DWORD dwStrType;
    DWORD dwCount;
    LPTSTR szSubjectRDN = NULL;

    dwStrType = CERT_X500_NAME_STR;
    dwCount = CertGetNameString(pCertCtx,
        CERT_NAME_RDN_TYPE,
        0,
        &dwStrType,
        NULL,
        0);
    if (dwCount)
    {
        szSubjectRDN = (LPTSTR)LocalAlloc(0, dwCount * sizeof(TCHAR));
        CertGetNameString(pCertCtx,
            CERT_NAME_RDN_TYPE,
            0,
            &dwStrType,
            szSubjectRDN,
            dwCount);
    }

    return szSubjectRDN;
}


int _tmain(int argc, _TCHAR* argv[])
{
    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_FILE_INFO sWintrustFileInfo;
    WINTRUST_DATA      sWintrustData;
    HRESULT            hr;

    if (argc != 2)
    {
        _tprintf(_T("Usage: VerifyExeSignature file_name\n"));
    //    return -1;
    }
    argv[1] = L"C:\\ChkProof_LinJian\\ChkProof_LinJian.exe";
    memset((void*)&sWintrustFileInfo, 0x00, sizeof(WINTRUST_FILE_INFO));
    memset((void*)&sWintrustData, 0x00, sizeof(WINTRUST_DATA));

    sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
    sWintrustFileInfo.pcwszFilePath = argv[1];
    sWintrustFileInfo.hFile = NULL;

    sWintrustData.cbStruct = sizeof(WINTRUST_DATA);
    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    sWintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    sWintrustData.pFile = &sWintrustFileInfo;
    sWintrustData.dwStateAction = WTD_STATEACTION_VERIFY;

    hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

    if (TRUST_E_NOSIGNATURE == hr)
    {
        _tprintf(_T("No signature found on the file.\n"));
    }
    else if (TRUST_E_BAD_DIGEST == hr)
    {
        _tprintf(_T("The signature of the file is invalid\n"));
    }
    else if (TRUST_E_PROVIDER_UNKNOWN == hr)
    {
        _tprintf(_T("No trust provider on this machine can verify this type of files.\n"));
    }
    else if (S_OK != hr)
    {
        _tprintf(_T("WinVerifyTrust failed with error 0x%.8X\n"), hr);
    }
    else
    {
        _tprintf(_T("File signature is OK.\n"));

        // retreive the signer certificate and display its information
        CRYPT_PROVIDER_DATA const *psProvData = NULL;
        CRYPT_PROVIDER_SGNR       *psProvSigner = NULL;
        CRYPT_PROVIDER_CERT       *psProvCert = NULL;
        FILETIME                   localFt;
        SYSTEMTIME                 sysTime;

        psProvData = WTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
        if (psProvData)
        {
            psProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0, FALSE, 0);
            if (psProvSigner)
            {
                FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
                FileTimeToSystemTime(&localFt, &sysTime);

                _tprintf(_T("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

                psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0);
                if (psProvCert)
                {
                    LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                    if (szCertDesc)
                    {
                        _tprintf(_T("File Signer = %s\n"), szCertDesc);
                        LocalFree(szCertDesc);
                    }
                }

                if (psProvSigner->csCounterSigners)
                {
                    _tprintf(_T("\n"));
                    // Timestamp information
                    FileTimeToLocalFileTime(&psProvSigner->pasCounterSigners[0].sftVerifyAsOf, &localFt);
                    FileTimeToSystemTime(&localFt, &sysTime);

                    _tprintf(_T("Timestamp Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
                    psProvCert = WTHelperGetProvCertFromChain(&psProvSigner->pasCounterSigners[0], 0);
                    if (psProvCert)
                    {
                        LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                        if (szCertDesc)
                        {
                            _tprintf(_T("Timestamp Signer = %s\n"), szCertDesc);
                            LocalFree(szCertDesc);
                        }
                    }
                }
            }
        }
    }

    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
    WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

    return 0;

}
复制代码

 

posted on   lydstory  阅读(1135)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2018-04-16 查看程序内存是否泄露
2018-04-16 Ubuntu 安装QT5 后编译程序报错: FindQt5Widgets.cmake
2018-04-16 pcd转换ply
2018-04-16 点云数据保存为pcd文件_pcd_write.cpp

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示