将 Windows PRIVATEKEYBLOB 转换为 Qt's QSslKey [英] Converting Windows PRIVATEKEYBLOB to Qt's QSslKey

查看:29
本文介绍了将 Windows PRIVATEKEYBLOB 转换为 Qt's QSslKey的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用 SSL 加密的 Qt 应用程序(Windows 服务).

I am working on an Qt application(Windows Service) which uses SSL encryption.

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

I need to access the certificate and associated private key from the Windows Certificate Store and pass it to my QSslSocket using setLocalCertificate and setPrivateKey which accepts QSslCertificate and QSslKey respectively.

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

I am able to get the certificate from the store and set it to QsslSocket using the Windows API '(CertOpenStore, CertFindCertificateInStore). Now as I have the certificate I need to extract its private key and set to ssl socket. I am using CryptAcquireCertificatePrivateKey, CryptGetUserKey and CryptExportKey Windows API in the same order, which gives me a Microsoft PRIVATEKEYBLOB and now I need to convert it to a format that QSslKey understands.

我该怎么做?

推荐答案

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

Solved it!! Thought of sharing teh solution here, it might be helpful to someone.

// 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);

这篇关于将 Windows PRIVATEKEYBLOB 转换为 Qt&amp;#39;s QSslKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆