问题描述
我希望能够获取您可以从 Windows 资源管理器获取的所有发行者数据,如下所示:
我已经能够从 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);
}