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

问题描述 投票:0回答:2

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

我已经能够从https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringw获取CN,但我不知道它是什么那个针对 CN 的调用(如果我这样做了,我也许能够弄清楚如何获取其他所有内容)。我尝试过在谷歌上搜索“api wintrust 发行者 CommonName Organization”和“wincrypt 组织 commonname”之类的内容,但这就像 API 洗掉了所有其他发行者数据一样。

c++ visual-studio winapi wincrypt
2个回答
1
投票

您只需使用

CertNameToStr
并设置
&(pCertContext->pCertInfo->Issuer)
参数即可:

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

我修改了官方示例供大家参考:

#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,
            NULL,
            NULL,
            0)))
        {
            MyHandleError(TEXT("CertGetName 1 failed."));
        }

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

        if (CertGetNameString(
            pCertContext,
            CERT_NAME_SIMPLE_DISPLAY_TYPE,
            0,
            NULL,
            pszName,
            cbSize))

        {
            _tprintf(TEXT("\nSubject -> %s.\n"), pszName);
            free(pszName);
        }
        else
        {
            MyHandleError(TEXT("CertGetName failed."));
        }
        if (!(cbSize = CertGetNameString(
            pCertContext,
            CERT_NAME_SIMPLE_DISPLAY_TYPE,
            CERT_NAME_ISSUER_FLAG,
            NULL,
            NULL,
            0)))
        {
            MyHandleError(TEXT("CertGetName 1 failed."));
        }

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

        if (CertGetNameString(
            pCertContext,
            CERT_NAME_SIMPLE_DISPLAY_TYPE,
            CERT_NAME_ISSUER_FLAG,
            NULL,
            pszName,
            cbSize))
        {
            _tprintf(TEXT("Issuer  -> %s.\n"), pszName);
            free(pszName);
        }
        else
        {
            MyHandleError(TEXT("CertGetName failed."));
        }
        cbSize = CertNameToStr(
            pCertContext->dwCertEncodingType,
            &(pCertContext->pCertInfo->Subject),
            MY_STRING_TYPE,
            NULL,
            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,
            &(pCertContext->pCertInfo->Issuer),
            CERT_X500_NAME_STR,
            pszString,
            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,
            pszString,
            MY_STRING_TYPE,
            NULL,
            NULL,        // 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,
            pszString,
            MY_STRING_TYPE,
            NULL,
            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);
} 

0
投票

我正在使用 CertGetNameStringW

进行此操作
std::wstring subjectString(PCCERT_CONTEXT pCertContext) const
{
    DWORD dwStrType = CERT_X500_NAME_STR;

    // Ensure we have a valid certificate context
    if (!pCertContext) {
        return L"";
    }

    // Get the size needed for the subject's name
    DWORD dwSubjectNameStrSize = CertGetNameStringW(
        pCertContext,
        CERT_NAME_RDN_TYPE,
        0,
        &dwStrType,
        NULL,
        0
    );

    if (dwSubjectNameStrSize > 0) {
        // Allocate memory for the subject's name
        std::wstring subjectName(dwSubjectNameStrSize-1, L'\0');
        
        // Get the subject's name
        if (CertGetNameStringW(
            pCertContext,
            CERT_NAME_RDN_TYPE,
            0,
            &dwStrType,
            subjectName.data(),
            dwSubjectNameStrSize
        ) <= 0) {

            throw win32error("Extracting subject from certificate");
        }

        return subjectName;
    }

    return L"";
}
© www.soinside.com 2019 - 2024. All rights reserved.