4

我正在尝试通过临时根 CA 签署公钥/私钥对,接下来是以下步骤:

  1. 创建自签名根授权证书 ( CertCreateSelfSignCertificate) (完成)
  2. 生成公钥/私钥对 ( CryptGenKey) (完成)
  3. 通过根授权证书( TODO )签署公钥/私钥对(我一直在尝试使用CertCreateSelfSignCertificate函数,但似乎不可能......)

我一直在按照下一个链接中提到的步骤进行操作: link

使用 powershell 可以正常工作,但我不知道如何使用 Microsoft CryptoApi C++ 来实现它。示例 Powershell:

$testCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "SignedByRootCA" -KeyExportPolicy Exportable -KeyLength 2048 -KeyUsage DigitalSignature,KeyEncipherment -Signer $rootCert

目前,我获得了没有私钥的证书,那么如何为我的签名证书分配私钥?我当前的代码如下所示:

// Open the CA cert to get the issuer information and a handle to sign the cert
PCCERT_CONTEXT caCert = NULL;
CertificateStore certStore{};
certStore.Open(certStore.ROOT);
certStore.FindCertContext(tmpThumbprint, caCert);
NCRYPT_KEY_HANDLE caKey = NULL;
DWORD caKeySpec = 0;
BOOL fCallerFreeProvOrNCryptKey = FALSE;
CryptAcquireCertificatePrivateKey(caCert, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &caKey, &caKeySpec, &fCallerFreeProvOrNCryptKey);

// A structure which contains the information of a certificate
CERT_INFO certificateInfo;
memset(&certificateInfo, 0, sizeof(CERT_INFO));
certificateInfo.dwVersion = CERT_V3;
certificateInfo.SignatureAlgorithm = signatureAlgorithm;
certificateInfo.NotBefore = notBefore;
certificateInfo.NotAfter = notAfter;
certificateInfo.Issuer = caCert->pCertInfo->Subject;
certificateInfo.Subject = static_cast<CERT_NAME_BLOB>(*subject);
certificateInfo.cExtension = 1;
certificateInfo.rgExtension = certExt;
BYTE serialNumber[16];
CryptGenRandom(caKey, 16, serialNumber);
certificateInfo.SerialNumber.pbData = serialNumber;
certificateInfo.SerialNumber.cbData = 16;

// Exports the public key information associated with the corresponding private key of the provider.
bool result = false;
PCERT_PUBLIC_KEY_INFO pkInfo = NULL;
CryptExportPublicKeyInfo(csp.Get(), AT_KEYEXCHANGE, X509_ASN_ENCODING, NULL, &cbEncode);
pkInfo = (PCERT_PUBLIC_KEY_INFO)malloc(cbEncode);
CryptExportPublicKeyInfo(csp.Get(), AT_KEYEXCHANGE, X509_ASN_ENCODING, pkInfo, &cbEncode);
certificateInfo.SubjectPublicKeyInfo = *pkInfo;

// Encode and sign Certificate and decode
result = CryptSignAndEncodeCertificate(caKey, caKeySpec, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &certificateInfo, &signatureAlgorithm, NULL, nullptr, &cbEncode);
pbEncode = (BYTE*)malloc(cbEncode);
result = CryptSignAndEncodeCertificate(caKey, caKeySpec, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &certificateInfo, &signatureAlgorithm, NULL, pbEncode, &cbEncode);
PCCERT_CONTEXT certContext = CertCreateCertificateContext(X509_ASN_ENCODING, pbEncode, cbEncode);
result = CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &caKey, &caKeySpec, &fCallerFreeProvOrNCryptKey); //FAILS!!! Error NTE_BAD_PUBLIC_KEY
DWORD e = GetLastError();

有什么办法吗?

4

0 回答 0