问题描述
我正在尝试将证书添加到商店,但我是新手。我一直在寻找有关如何安装证书以存储而没有从商店中找到证书上下文的信息(我在商店中没有证书)。我发现的所有东西都在下面的代码中使用过。但它似乎不起作用,即使在安装证书的消息后,我也无法在商店中找到证书。
static HCRYPTPROV hProv = 0;
static HCRYPTKEY hKey = 0;
static unsigned char *pbKeyBlob = nullptr;
static unsigned int cbKeyBlob;
static unsigned int cbCertBlob;
static unsigned char *pbCertBlob = nullptr;
LPCSTR szCont = "myCont";
if(CryptAcquireContext(&hProv,szCont,nullptr,PROV_GOST_2012_256,0))
{
qDebug() << "The key container \"%s\" has been acquired.\n" << szCont;
}
else
{
HandleError("Error during CryptAcquireContext.");
}
if(CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hKey))
{
qDebug() << "The public key has been acquired. \n";
}
else
{
HandleError("Error during CryptGetUserKey public key.");
}
if(CryptExportKey(hKey,PUBLICKEYBLOB,&cbKeyBlob))
{
qDebug() << "Size of the BLOB for the public key determined. \n";
}
else
{
HandleError("Error computing BLOB length.");
}
pbKeyBlob = static_cast<unsigned char*>(malloc(cbKeyBlob));
if(!pbKeyBlob)
{
HandleError("Out of memory. \n");
}
if(CryptExportKey(hKey,pbKeyBlob,&cbKeyBlob))
{
qDebug() << "Contents have been written to the BLOB. \n";
}
else
{
HandleError("Error during CryptExportKey.");
}
if(CryptGetKeyParam(hKey,KP_CERTIFICATE,&cbCertBlob,0))
{
pbCertBlob = static_cast<unsigned char*>(malloc(cbCertBlob));
if(!pbCertBlob)
{
HandleError("Out of memory. \n");
}
szFileName = static_cast<char*>(malloc((strlen(szCont) + 5) * sizeof(char)));
if(!szFileName)
{
HandleError("Out of memory. \n");
}
if(CryptGetKeyParam(hKey,pbCertBlob,0))
{
qDebug() << "Got certificate from container.\n";
}
else
{
HandleError("Error during CryptGetKeyParam.");
}
strcpy(szFileName,szCont);
strcat(szFileName,".cer");
WriteBlobToFile(Cert,cbCertBlob);
pDesiredCert = CertCreateCertificateContext(MY_ENCODING_TYPE,cbCertBlob);
hCertStore = CertOpenSystemStore(0,"mRoot");
这里我没有收到任何错误,甚至看起来好像安装成功了,但我在证书存储中什么也没找到。
if (!CertAddEncodedCertificatetoStore(hCertStore,MY_ENCODING_TYPE,pDesiredCert->pbCertEncoded,pDesiredCert->cbCertEncoded,CERT_STORE_ADD_NEW,&pDesiredCert))
{
qDebug() << "Cartificate installing Failed.";
}
else
{
qDebug() << "Certificate was installed successfully to mRoot store.";
}
解决方法
最好使用makecert、openssl等专用工具创建证书。之后,根据Serializing Certificates可以将其添加到证书存储中。
编辑:
makecert.exe -$ individual -n "CN=Test Signing Cert" -r C:\Users\public_v2.crt
然后
#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(const char* s);
int main()
{
// usage: CertExtract certpath
char keyFile[] = "C:\\Users\\public_v2.crt";
BYTE lp[65536];
SECURITY_ATTRIBUTES sa;
HANDLE hKeyFile;
DWORD bytes;
HCERTSTORE hFileStore;
PCCERT_CONTEXT certContext;
HCERTSTORE hSystemStore;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
hKeyFile = CreateFile(keyFile,GENERIC_READ,FILE_SHARE_READ,&sa,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hKeyFile) {
if (ReadFile(hKeyFile,lp,GetFileSize(hKeyFile,NULL),&bytes,NULL) && bytes > 0) {
certContext = CertCreateCertificateContext(X509_ASN_ENCODING,bytes);
if (certContext) {
printf("yay!");
/*if (hFileStore = CertOpenStore(
CERT_STORE_PROV_FILENAME,MY_ENCODING_TYPE,NULL,L"testStor.sto"))
{
printf("The file store is open. Continue.\n");
}
else
{
MyHandleError("The file store did not open.");
}*/
if (hSystemStore = CertOpenSystemStore(
0,"CA"))
{
printf("The CA system store is open. Continue.\n");
}
else
{
MyHandleError("The first system store did not open.");
}
if (CertAddEncodedCertificateToStore(
hSystemStore,certContext->pbCertEncoded,certContext->cbCertEncoded,CERT_STORE_ADD_NEW,&certContext))
{
printf("Another certificate is added to the file store.\n");
}
else
{
MyHandleError("The new certificate was not added to the "
"file store.");
}
/*if (CertSaveStore(
hFileStore,CERT_STORE_SAVE_AS_PKCS7,CERT_STORE_SAVE_TO_FILENAME,(void*)L"testStor.sto",0))
{
printf("Another certificate is saved to the file store.\n");
}
else
{
MyHandleError("The new certificate was not added to the "
"file store.");
}*/
//-------------------------------------------------------------------
// Free memory.
CertCloseStore(hSystemStore,0);
//CertCloseStore(hFileStore,0);
printf("The program ran without error to the end.\n");
CertFreeCertificateContext(certContext);
}
else {
printf("Could not convert certificate to internal form\n");
}
}
else {
printf("Failed to read key file: %s\n",keyFile);
}
}
else {
printf("Failed to open key file: %s\n",keyFile);
}
CloseHandle(hKeyFile);
return 0;
}
//-------------------------------------------------------------------
// This example uses the function MyHandleError,a simple error
// handling function,to print an error message to the standard
// error (stderr) file and exit the program.
// For most applications,replace this function with one
// that does more extensive error reporting.
void MyHandleError(const 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