将Windows PRIVATEKEYBLOB转换为Qt的QSslKey

我正在使用SSLencryption的Qt应用程序(Windows服务)。

我需要从Windows证书存储中访问证书和关联的私钥,并使用setLocalCertificate和setPrivateKey分别接受QSslCertificate和QSslKey将其传递给我的QSslSocket。

我能够从商店获取证书,并使用Windows API(CertOpenStore,CertFindCertificateInStore)将其设置为QsslSocket。 现在,我有证书,我需要提取其私钥,并设置为ssl套接字。 我正在使用CryptAcquireCertificatePrivateKey,CryptGetUserKey和CryptExportKey Windows API以相同的顺序,这给了我一个Microsoft PRIVATEKEYBLOB,现在我需要将其转换为QSslKey理解的格式。

我怎么做?

Solutions Collecting From Web of "将Windows PRIVATEKEYBLOB转换为Qt的QSslKey"

解决了它! 想到在这里分享这个解决方案,可能对某个人有帮助。

// Open the certificate store to be searched. HCERTSTORE hSystemStore = CertOpenStore((LPCSTR)(CERT_STORE_PROV_SYSTEM), 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY"); CRYPT_DATA_BLOB dataBlob = {0}; QString password("password"); // your password for the cretificate and private key goes here if(PFXExportCertStoreEx(hSystemStore, &dataBlob, password.toStdWString().c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | REPORT_NO_PRIVATE_KEY)) { if (dataBlob.cbData > 0) { dataBlob.pbData = (BYTE*)malloc(dataBlob.cbData); if (PFXExportCertStoreEx(hSystemStore, &dataBlob, password.toStdWString().c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | REPORT_NO_PRIVATE_KEY)) { EVP_PKEY *pkey; X509 *cert; STACK_OF(X509) *ca = NULL; PKCS12 *p12; int i; CRYPTO_malloc_init(); OpenSSL_add_all_algorithms(); SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); BIO* input = BIO_new_mem_buf((void*)dataBlob.pbData, dataBlob.cbData); p12 = d2i_PKCS12_bio(input, NULL); PKCS12_parse(p12, password.toStdString().c_str(), &pkey, &cert, &ca); PKCS12_free(p12); if (cert) { BIO *boCert = BIO_new( BIO_s_mem() ); PEM_write_bio_X509(boCert, cert); if (ca && sk_X509_num(ca)) { for (i = 0; i < sk_X509_num(ca); i++) { PEM_write_bio_X509(boCert, sk_X509_value(ca, i)); } } char *certStr; long len = BIO_get_mem_data(boCert, &certStr); QSslCertificate localCertificate(QByteArray::fromRawData(certStr, len)); mySslSocket->setLocalCertificate(localCertificate); BIO_free_all(boCert); } if (pkey) { BIO *bo = BIO_new( BIO_s_mem() ); PEM_write_bio_PrivateKey(bo, pkey, NULL, (unsigned char*)(password.toStdString().c_str()), password.length(), NULL, (char*)(password.toStdString().c_str())); char *p; long len = BIO_get_mem_data(bo, &p); QSslKey key(QByteArray::fromRawData(p, len), QSsl::Rsa); mySslSocket->setPrivateKey(key); BIO_free_all(bo); } free(dataBlob.pbData); } } } if(hSystemStore) CertCloseStore(hSystemStore, 0);