преобразование сертификатов pfx в формат PEM

Я нашел этот вопрос Преобразование .PFX в .PEM программно?
и у меня та же проблема программного экспорта сертификатов и закрытого ключа в формате pfx из хранилища ключей Windows и преобразования их в файл / память формата PEM.

Вышеприведенная ссылка, кажется, делает это, но никакой реальной информации о том, как это было сделано, и внутренние ссылки на github, похоже, не работают

Мы не можем использовать формат pfx, потому что он содержит цепочку сертификатов и API библиотеки openSSL для загрузки такой цепочки сертификатов, работает только для файла PEM.

Когда файл pfx был импортирован в хранилище ключей Windows, закрытый ключ был проверен как экспортируемый.

Мне удалось экспортировать сертификаты, скопировав их в новое хранилище памяти, экспортировать их в память памяти и сохранить в файл в различных форматах (base64 и двоичный) — см. Код ниже — но я не уверен, что это правильный способ сделать это, если вся цепочка была экспортирована, и я также не знаю, как преобразовать ее в формат PEM

Заранее благодарю за любую помощь

#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);

char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);

void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE         hSystemStore;
HCERTSTORE         hTempStore;
PCCERT_CONTEXT     pCertContext = NULL;
char pszStoreName[256] = "root";
char               pszNameString[256] = "xyzabcfkjvfkvnrg";

//-------------------------------------------------------------------
// Open a system certificate store.
if(hSystemStore = CertOpenSystemStore(
0,
pszStoreName))
{
printf("The %s system store is open. Continue.\n", pszStoreName );
}
else
{
MyHandleError("The first system store did not open.");
}

//-------------------------------------------------------------------
// Open a temporary certificate store.
if(hTempStore = CertOpenStore(
CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, 0 ))
{
printf("Temp certificate store was created. Continue.\n");
}
else
{
MyHandleError("The temp store wasn't not created.");
}
//-------------------------------------------------------------------
// Get a certificate that has the desired friendly name.
if(pCertContext=CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE,             // Use X509_ASN_ENCODING
0,                            // No dwFlags needed
CERT_NAME_FRIENDLY_DISPLAY_TYPE,        // Find a certificate
pszNameString, // The Unicode string to be found
// in a certificate's subject
NULL))                        // NULL for the first call
{
printf("The %s certificate was found. \n", pszNameString);
}
else
{
MyHandleError("Could not find the %s certificate.");
}

//------------------------------------------------------------------
// add selected certificate into temporary store in memory

if(CertAddCertificateContextToStore(hTempStore, pCertContext, CERT_STORE_ADD_NEW, 0))
{
printf("The %s certificate was added. \n", pszNameString);
}
else
{
MyHandleError("Could not add %s ce#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);

char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);

void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE         hSystemStore;
HCERTSTORE         hTempStore;
PCCERT_CONTEXT     pCertContext = NULL;
char pszStoreName[256] = "root";
char               pszNameString[256] = "xyzabcfkjvfkvnrg";

//-------------------------------------------------------------------
// Open a system certificate store.
if(hSystemStore = CertOpenSystemStore(
0,
pszStoreName))
{
printf("The %s system store is open. Continue.\n", pszStoreName );
}
else
{
MyHandleError("The first system store did not open.");
}

//-------------------------------------------------------------------
// Open a temporary certificate store.
if(hTempStore = CertOpenStore(
CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, 0 ))
{
printf("Temp certificate store was created. Continue.\n");
}
else
{
MyHandleError("The temp store wasn't not created.");
}
//-------------------------------------------------------------------
// Get a certificate that has the desired friendly name.
if(pCertContext=CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE,             // Use X509_ASN_ENCODING
0,                            // No dwFlags needed
CERT_NAME_FRIENDLY_DISPLAY_TYPE,        // Find a certificate
pszNameString, // The Unicode string to be found
// in a certificate's subject
NULL))                        // NULL for the first call
{
printf("The %s certificate was found. \n", pszNameString);
}
else
{
MyHandleError("Could not find the %s certificate.");
}

//------------------------------------------------------------------
// add selected certificate into temporary store in memory

if(CertAddCertificateContextToStore(hTempStore, pCertContext, CERT_STORE_ADD_NEW, 0))
{
printf("The %s certificate was added. \n", pszNameString);
}
else
{
MyHandleError("Could not add %s certificate.");
}

//------------------------------------------------------------------------------CRYPT_DATA_BLOB* db= new (CRYPT_DATA_BLOB);
LPCWSTR szPassword = NULL;
db->cbData = 0;

if((!PFXExportCertStoreEx(
hTempStore,
db,
szPassword,
0,
EXPORT_PRIVATE_KEYS|REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))&&(GetLastError()==0))
{
printf("The %s certificate blob size is %d. \n", pszNameString, db->cbData);
}
else
{
MyHandleError("Could not calculate size of certificate.");
}

//-------------------------------------------------------
// Allocate memory
if(db->pbData = (BYTE*)malloc(db->cbData+1))
{
printf("Memory has been allocated. Continue.\n");
}
else
{
MyHandleError("The allocation of memory failed.");
}

// Export certificate from temporary store to blob

if(PFXExportCertStoreEx(
hTempStore,
db,
szPassword,
0,
EXPORT_PRIVATE_KEYS|REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
{
printf("The %s certificate blob was exported %d. \n", pszNameString);
}
else
{
MyHandleError("Could not export certificate.");
}//-------------------------------------------------------------------
//Write blob to files

FILE *fp;
errno_t err;
if ((err = fopen_s(&fp, "cert_bin.p12", "wb")) != 0)
printf("File was not opened\n");
else
for (int i=0; i<db->cbData; i++)
fprintf(fp,"%c", db->pbData + i);
fclose(fp);

size_t t;
char* c = base64_encode(db->pbData, db->cbData, &t);

if ((err = fopen_s(&fp, "cert_base64.p12", "w")) != 0)
printf("File was not opened\n");
else
fprintf(fp, "%s", c);
fclose(fp);

//-------------------------------------------------------------------
// Free memory.

//free(pbElement);
CertCloseStore(hSystemStore,0);
printf("The program ran without error to the end.\n");
} // End of main

//-------------------------------------------------------------------
void MyHandleError(char *s)
{
fprintf(stderr,"An error occurred in running the program. \n");
fprintf(stderr,"%s\n",s);
fprintf(stderr, "Error number %x.\n", GetLastError());
fprintf(stderr, "Program terminating. \n");
exit(1);
} // End of MyHandleError

0

Решение

Этот фрагмент цепочки сертификатов экспорта из WCS в файл pfx

{
CString errorS = NULL;
CString  pkcs12File = pszNameString;
CString szPassword = L"XXXXXXXXX";
do {
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE         hSystemStore = NULL;
HCERTSTORE         hTempStore = NULL;
PCCERT_CONTEXT     pCertContext = NULL;

//-------------------------------------------------------------------
// Open a system certificate store.
if (!(hSystemStore = CertOpenSystemStore(
0,
(LPCWSTR)pszStoreName)))
{
errorS = ("system store did not open.");
break;
}

//-------------------------------------------------------------------
// Open a temporary certificate store.
if (!(hTempStore = CertOpenStore(
CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, 0)))
{
errorS = ("The temp store wasn't created.");
break;
}

//-------------------------------------------------------------------
// Get a certificate that has the desired friendly name.
if (!(pCertContext = CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE,             // Use X509_ASN_ENCODING
0,                            // No dwFlags needed
CERT_FIND_SUBJECT_STR,        // Find a certificate
pszNameString, // The Unicode string to be found
// in a certificate's subject
NULL)))                        // NULL for the first call
{
errorS = ("Could not find the certificate . " + pszNameString);
break;
}

//-------------------------------------------------------------------
PCCERT_CHAIN_CONTEXT     pChainContext = NULL;
CERT_CHAIN_PARA          ChainPara;
DWORD                    dwFlags = 0;
CERT_ENHKEY_USAGE        EnhkeyUsage;
CERT_USAGE_MATCH         CertUsage;

EnhkeyUsage.cUsageIdentifier = 0;
EnhkeyUsage.rgpszUsageIdentifier = NULL;
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage = CertUsage;

if (!CertGetCertificateChain(
NULL,                  // use the default chain engine
pCertContext,          // pointer to the end certificate
NULL,                  // use the default time
NULL,                  // search no additional stores
&ChainPara,            // use AND logic and enhanced key usage
//  as indicated in the ChainPara
//  data structure
dwFlags,
NULL,                  // currently reserved
&pChainContext))       // return a pointer to the chain created
{
errorS = ("Could not get certificate chain.");
break;
}

//------------------------------------------------------------------
// add selected certificate into temporary store in memory
for (int l_chain = 0; l_chain < (int)(pChainContext->cChain); l_chain++)
for (int l_cert = 0; l_cert < (int)(pChainContext->rgpChain[l_chain]->cElement); l_cert++)
{
pCertContext = (PCCERT_CONTEXT)pChainContext->rgpChain[l_chain]->rgpElement[l_cert]->pCertContext;
if (!(CertAddCertificateContextToStore(hTempStore, pCertContext, CERT_STORE_ADD_NEW, 0)))
{
errorS = ("Could not add certificate.");
break;
}
}

CertFreeCertificateChain(pChainContext);

//------------------------------------------------------------------------------
// Export certificates chain to memory bolb

CRYPT_DATA_BLOB* db = new (CRYPT_DATA_BLOB);
LPCWSTR szPassword = L"XXXXXXXXX";
db->cbData = 0;

// calculating required memory space

if ((PFXExportCertStoreEx(
hTempStore,
db,
szPassword,
0,
EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) && (GetLastError() == 0))
{
errorS = ("Could not calculate size of certificate.");
break;
}

// Allocate memory
if (!(db->pbData = (BYTE*)malloc(db->cbData)))
{
errorS = ("The allocation of memory failed.");
break;
}

// Export certificate from temporary store to blob

if (!PFXExportCertStoreEx(
hTempStore,
db,
szPassword,
0,
EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY))
{
errorS = ("Could not export certificate.");
break;
}

//-------------------------------------------------------------------
//Write blob to files

FILE *fp = NULL;
errno_t err;
if ((err = fopen_s(&fp, CT2A(pkcs12File), "wb")) != 0)
{
errorS = ("File was not opened\n");
break;
}
else
fwrite(db->pbData, 1, db->cbData, fp);
fclose(fp);
//-------------------------------------------------------------------
// Free memory.

CertCloseStore(hSystemStore, 0);

//--------------------------------------------------------------------------

} while (0);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]