我希望能够获取您可以从 Windows 资源管理器获取的所有发行人数据,如下所示:
我已经能够从https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetnamestringw获取CN,但我不知道它是什么那个针对 CN 的调用(如果我这样做了,我也许能够弄清楚如何获取其他所有内容)。我尝试过在谷歌上搜索“api wintrust 发行者 CommonName Organization”和“wincrypt 组织 commonname”之类的内容,但这就像 API 洗掉了所有其他发行者数据一样。
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);
}
我正在使用 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"";
}