Windows上的OpenSSL可以使用系统证书存储吗?

问题描述 投票:29回答:4

我正在从Linux移植到Windows的一些正在运行的C ++代码在Windows上失败,因为SSL_get_verify_result()正在返回X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

代码在Linux上使用SSL_CTX_set_default_verify_paths()告诉SSL只查看证书存储的标准默认位置。

是否可以让OpenSSL使用系统证书存储?

c++ windows openssl
4个回答
42
投票

我早点完成了。希望这有帮助,如果这正是您正在寻找的。

  1. 使用Crypto API从Windows Cert存储加载证书(在PCCERT_CONTEXT结构中)。
  2. 以二进制格式获取加密内容。 [PCCERT_CONTEXT->pbCertEncoded]。
  3. 使用OpenSSL的d2i_X509()方法将此二进制缓冲区解析为X509证书对象。
  4. 使用SSL_CTX_get_cert_store()方法获取OpenSSL信任库的句柄。
  5. 使用X509_STORE_add_cert()方法将解析的X509证书加载到此信任库中。
  6. 你完成了!

15
投票

对于那些仍在努力解决这个问题的人来说,这里有一个示例代码可以帮助您入门:

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <cryptuiapi.h>
#include <iostream>
#include <tchar.h>

#include "openssl\x509.h"

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

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

int main(void)
{
    HCERTSTORE hStore;
    PCCERT_CONTEXT pContext = NULL;
    X509 *x509;
    X509_STORE *store = X509_STORE_new();

    hStore = CertOpenSystemStore(NULL, L"ROOT");

    if (!hStore)
        return 1;

    while (pContext = CertEnumCertificatesInStore(hStore, pContext))
    {
        //uncomment the line below if you want to see the certificates as pop ups
        //CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pContext,   NULL, NULL, 0, NULL);

        x509 = NULL;
        x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded);
        if (x509)
        {
            int i = X509_STORE_add_cert(store, x509);

            if (i == 1)
                std::cout << "certificate added" << std::endl;

            X509_free(x509);
        }
    }

CertFreeCertificateContext(pContext);
CertCloseStore(hStore, 0);
system("pause");
return 0;

}

3
投票

No. Not out of the box.

不,它不可能开箱即用。这需要额外的编程。使用OpenSSL,您有两个(开箱即用)选项:

  1. 使用OpenSSL自己的证书存储区(它是由OpenSSL提供的perl脚本创建的目录层次结构)
  2. 仅使用您创建的证书链文件(它是一个文本文件,其中包含信任链中的所有PEM编码证书)。创建这样的文件很简单(只需附加它)

1
投票

Yes

可以像往常一样使用OpenSSL进行操作,并仅将CryptoAPI用于证书验证过程。我在这里看到了关于这个主题的几个主题,并且大多数都是tip / to脚尖。

有了CryptoAPI你必须:

  • PEM解码DERCryptStringToBinary()
  • CERT_CONTEXT创建一个CertCreateCertificateContext()对象
  • 并通过众所周知/文件化的程序验证此表格中的证书。 (例如here at ETutorials。) 要完成最后一步,您还需要为HCERTSTOREMYROOT系统商店中的一个初始化CA,或者迭代它们......这取决于您想要的行为。
© www.soinside.com 2019 - 2024. All rights reserved.