Windows上的OpenSSL可以使用系统证书存储吗? < >我从Linux移植到Windows的一些工作C++代码在Windows上失败,因为 SSLGETGEVILIFY(RESULTE)>代码>正在返回 X509YVYRYLununabytotoGigiSuxErr.CytTyTealOp/。p>

Windows上的OpenSSL可以使用系统证书存储吗? < >我从Linux移植到Windows的一些工作C++代码在Windows上失败,因为 SSLGETGEVILIFY(RESULTE)>代码>正在返回 X509YVYRYLununabytotoGigiSuxErr.CytTyTealOp/。p>,c++,windows,openssl,C++,Windows,Openssl,代码在Linux上使用SSL\u CTX\u set\u default\u verify\u path()告诉SSL只需查看证书存储的标准默认位置 是否可以让OpenSSL使用系统证书存储?否。不是现成的。 不,不可能开箱即用。这将需要额外的编程。使用OpenSSL,您有两个现成的选项: 使用OpenSSL自己的证书存储(它是由OpenSSL提供的perl脚本创建的目录层次结构) 仅使用您创建的证书链文件(它是一个文本文件,在信任链中包含所有PEM编码的证书)。创建这样的文件很容易(只需附加它

代码在Linux上使用
SSL\u CTX\u set\u default\u verify\u path()
告诉SSL只需查看证书存储的标准默认位置

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

否。不是现成的。 不,不可能开箱即用。这将需要额外的编程。使用OpenSSL,您有两个现成的选项:

  • 使用OpenSSL自己的证书存储(它是由OpenSSL提供的perl脚本创建的目录层次结构)
  • 仅使用您创建的证书链文件(它是一个文本文件,在信任链中包含所有PEM编码的证书)。创建这样的文件很容易(只需附加它)
  • 我以前做过。 希望这有帮助,如果这正是你想要的

  • 使用加密API从Windows证书存储加载您的证书(在
    PCCERT\u上下文
    structure中)
  • 按原样以二进制格式获取加密内容。[
    PCCERT\u CONTEXT->pbcertcoded
    ]
  • 使用OpenSSL的
    d2i_X509()
    方法将此二进制缓冲区解析为X509证书对象
  • 使用
    SSL\u CTX\u Get\u cert\u store()
    方法获取OpenSSL信任存储的句柄
  • 使用
    X509\u store\u add\u cert()
    方法将以上解析的X509证书加载到此信任存储
  • 你完了 对 可以像往常一样使用
    OpenSSL
    进行操作,也可以仅在证书验证过程中使用
    CryptoAPI
    。我在这里看到了关于这个主题的几条线索,大多数都是踮着脚尖绕来绕去的

    使用
    CryptoAPI
    您必须:

    • 使用
      CryptStringToBinary()
      PEM
      解码为
      DER

    • 使用
      CertCreateCertificateContext()

    • 并通过众所周知的/文件化的程序验证此表格中的证书。(例如)

      要使最后一步正常工作,您还需要为
      MY
      ROOT
      CA
      系统存储之一初始化
      HCERTSTORE
      ,或对其进行迭代。。。取决于你想要的行为


    对于像我这样仍在努力解决这一问题的人,下面是一个示例代码,可以帮助您开始:

    #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;
    
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括“openssl\x509.h”
    #pragma注释(lib,“crypt32.lib”)
    #pragma注释(lib,“cryptui.lib”)
    #定义MY_ENCODING_类型(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    内部主(空)
    {
    HCERTSTORE商店;
    PCCERT_CONTEXT pContext=NULL;
    X509*X509;
    X509_STORE*STORE=X509_STORE_new();
    hStore=CertOpenSystemStore(NULL,L“根”);
    如果(!hStore)
    返回1;
    while(pContext=CertEnumCertificateSinstare(hStore,pContext))
    {
    //如果要将证书作为弹出窗口查看,请取消注释下面的行
    //CryptUIDlgViewContext(证书存储证书上下文,pContext,NULL,NULL,0,NULL);
    x509=NULL;
    x509=d2i_x509(NULL,(常量unsigned char**)&pContext->pbcertcoded,pContext->cbcertcoded);
    如果(x509)
    {
    int i=X509\存储\添加\证书(存储,X509);
    如果(i==1)
    
    std::是否可以从windows pkcs文件在内存中创建PEM文件?然后加载?我发现:它描述了从pkcs包创建PEM文件…并描述了从缓冲区加载PEM文件的机制…?是的,这当然是可能的。哎呀…出于某种原因,它不喜欢我的文件(使用该页中的代码制作)…我本以为在我之前会有人这样做?我很好奇你是否可以评论一下@Tushar Sudake最近的解决方案…你认为这在OpenSSL中仍然是不可能的吗?是的,我认为这可能会起作用。此外,他写道他已经做到了,并且成功了。当我写道这是不可能的时候,我的意思是“直接不可能”(例如,OpenSSL直接使用来自Windows的证书)。感谢您提供的信息。我应该在此添加一些注意事项:1.使用“根”(而不是“CA”)枚举Windows的存储区.2.您需要在连接/握手之前添加证书,并在连接/握手之后进行验证,否则验证将失败。此方法的问题是它只验证中间证书。它不会验证您的中间证书是否直接受信任,而是验证其根是否受信任。我们如何验证根是否受信任是可信的,但不是中间证书?您使用的
    d2i_X509
    无效,因为
    d2i_X509
    参数中增加了
    *(您使用强制转换以避免编译器错误)。您必须使用临时变量来避免内存问题,例如:
    const unsigned char*encoded\u cert=win\u cert\u context->pbcertcoded;d2i\u X509(nullptr,&encoded\u cert,…
    pContext
    在传递到
    certFreeCerteCerteContext()
    时将为空(因为
    while
    循环不会提前中断),这样就没有必要打那个电话了。