Visual Studio:从可执行文件中获取所有证书颁发者详细信息

问题描述

我希望能够获取您可以从 Windows 资源管理器获取的所有发行者数据,如下所示:

Screen cap of the data I want

我已经能够从 https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringw 获取 CN,但我不知道针对 CN 的那个调用是什么(如果我这样做了,我可能会想出如何获取其他所有内容)。我试过在谷歌上搜索诸如“api wintrust issuer CommonName Organization”和“wincrypt organization commonname”之类的东西,但这就像 API 洗掉了所有其他发行者数据。

解决方法

您只需要使用 CertNameToStr 并设置 &(pCertContext->pCertInfo->Issuer) 参数:

CertNameToStr(
            pCertContext->dwCertEncodingType,&(pCertContext->pCertInfo->Issuer),CERT_X500_NAME_STR,pszString,cbSize);

我修改了 official sample 以供您参考:

#pragma comment(lib,"crypt32.lib")
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>

#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define MY_STRING_TYPE (CERT_OID_NAME_STR)
void MyHandleError(LPTSTR);

void main(void)
{
    HCERTSTORE hCertStore;
    PCCERT_CONTEXT pCertContext;
    if (!(hCertStore = CertOpenStore(
        CERT_STORE_PROV_SYSTEM,MY_ENCODING_TYPE,NULL,CERT_SYSTEM_STORE_CURRENT_USER,L"MY")))
    {
        MyHandleError(TEXT("The MY system store did not open."));
    }
    pCertContext = NULL;
    while (pCertContext = CertEnumCertificatesInStore(
        hCertStore,pCertContext))
    {
        LPTSTR pszString;
        LPTSTR pszName;
        DWORD cbSize;
        CERT_BLOB blobEncodedName;
        if (!(cbSize = CertGetNameString(
            pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,0)))
        {
            MyHandleError(TEXT("CertGetName 1 failed."));
        }

        if (!(pszName = (LPTSTR)malloc(cbSize * sizeof(TCHAR))))
        {
            MyHandleError(TEXT("Memory allocation failed."));
        }

        if (CertGetNameString(
            pCertContext,pszName,cbSize))

        {
            _tprintf(TEXT("\nSubject -> %s.\n"),pszName);
            free(pszName);
        }
        else
        {
            MyHandleError(TEXT("CertGetName failed."));
        }
        if (!(cbSize = CertGetNameString(
            pCertContext,CERT_NAME_ISSUER_FLAG,cbSize))
        {
            _tprintf(TEXT("Issuer  -> %s.\n"),pszName);
            free(pszName);
        }
        else
        {
            MyHandleError(TEXT("CertGetName failed."));
        }
        cbSize = CertNameToStr(
            pCertContext->dwCertEncodingType,&(pCertContext->pCertInfo->Subject),MY_STRING_TYPE,0);
        if (1 == cbSize)
        {
            MyHandleError(TEXT("Subject name is an empty string."));
        }
        if (!(pszString = (LPTSTR)malloc(cbSize * sizeof(TCHAR))))
        {
            MyHandleError(TEXT("Memory allocation failed."));
        }
        cbSize = CertNameToStr(
            pCertContext->dwCertEncodingType,cbSize);
        if (1 == cbSize)
        {
            MyHandleError(TEXT("Issuer name is an empty string."));
        }
        else
        {
            printf("Issuer String = %ls\n",pszString); //what you want
        }

        if (!(CertStrToName(
            MY_ENCODING_TYPE,// NULL to get the number of bytes 
                            // needed for the buffer.          
            &cbSize,// Pointer to a DWORD to hold the 
                            // number of bytes needed for the 
                            // buffer
            NULL)))     // Optional address of a pointer to
                            // old the location for an error in the 
                            // input string.
        {
            MyHandleError(
                TEXT("Could not get the length of the BLOB."));
        }
        if (!(blobEncodedName.pbData = (LPBYTE)malloc(cbSize)))
        {
            MyHandleError(
                TEXT("Memory Allocation for the BLOB failed."));
        }
        blobEncodedName.cbData = cbSize;

        if (CertStrToName(
            MY_ENCODING_TYPE,blobEncodedName.pbData,&blobEncodedName.cbData,NULL))
        {
            _tprintf(TEXT("CertStrToName created the BLOB.\n"));
        }
        else
        {
            MyHandleError(TEXT("Could not create the BLOB."));
        }
        free(blobEncodedName.pbData);
        free(pszString);
    }

    _tprintf(
        TEXT("\nThere are no more certificates in the store. \n"));
    if (CertCloseStore(
        hCertStore,CERT_CLOSE_STORE_CHECK_FLAG))
    {
        _tprintf(TEXT("The store is closed. ")
            TEXT("All certificates are released.\n"));
    }
    else
    {
        _tprintf(TEXT("The store was closed,")
            TEXT("but certificates still in use.\n"));
    }
    _tprintf(TEXT("This demonstration program ran to completion ")
        TEXT("without error.\n"));
} 

void MyHandleError(LPTSTR psz)
{
    _ftprintf(stderr,TEXT("An error occurred in running the program. \n"));
    _ftprintf(stderr,TEXT("%s\n"),psz);
    _ftprintf(stderr,TEXT("Error number %x.\n"),GetLastError());
    _ftprintf(stderr,TEXT("Program terminating. \n"));
    exit(1);
}