简体   繁体   English

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

[英]Can OpenSSL on Windows use the system certificate store?

Some working C++ code that I'm porting from Linux to Windows is failing on windows because SSL_get_verify_result() is returning X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY . 我从Linux移植到Windows的一些SSL_get_verify_result() C ++代码在Windows上失败,因为SSL_get_verify_result()返回X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

The code was using SSL_CTX_set_default_verify_paths() on Linux to tell SSL to just look in the standard default locations for the certificate store. 该代码在Linux上使用SSL_CTX_set_default_verify_paths()告诉SSL仅查看证书存储的标准默认位置。

Is it possible to get OpenSSL to use the system certificate store? 是否可以使OpenSSL使用系统证书存储?

I have done it earlier. 我已经做过了。 Hope this helps, if this is exactly what you are looking for. 如果这正是您想要的,希望对您有所帮助。

  1. Load your certificate (in PCCERT_CONTEXT structure) from Windows Cert store using Crypto APIs. 使用Crypto API从Windows证书存储区加载证书(以PCCERT_CONTEXT结构)。
  2. Get encrypted content of it in binary format as it is. 照原样以二进制格式获取其加密内容。 [ PCCERT_CONTEXT->pbCertEncoded ]. [ PCCERT_CONTEXT->pbCertEncoded ]。
  3. Parse this binary buffer into X509 certificate Object using OpenSSL's d2i_X509() method. 使用OpenSSL的d2i_X509()方法将此二进制缓冲区解析为X509证书对象。
  4. Get handle to OpenSSL's trust store using SSL_CTX_get_cert_store() method. 使用SSL_CTX_get_cert_store()方法获取OpenSSL信任存储的句柄。
  5. Load above parsed X509 certificate into this trust store using X509_STORE_add_cert() method. 使用X509_STORE_add_cert()方法将上面解析的X509证书加载到此信任存储中。
  6. You are done! 大功告成!

For those of you still struggling with this as I have been, here is a sample code to get you started: 对于像我一样一直在为此奋斗的那些人,以下示例代码可帮助您入门:

#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;

}

No. Not out of the box. 不,不是开箱即用的。

No it is not possible out of the box. 不,这是不可能的。 It would require additional programming. 这将需要其他编程。 With OpenSSL you have two (out of the box) options: 使用OpenSSL,您有两个(开箱即用的)选项:

  1. Use OpenSSL's own cert store (it is a hierarchy of directories created by perl script provided with OpenSSL) 使用OpenSSL自己的证书存储(这是由OpenSSL随附的perl脚本创建的目录层次结构)
  2. Use only a certificate chain file created by you (it is a text file with all PEM-encoded certificates in a chain of trust). 仅使用您创建的证书链文件(这是一个文本文件,在信任链中包含所有PEM编码的证书)。 Creating such a file is easy (just appending it) 创建这样的文件很容易(只需附加文件)

Yes

It is possible to use OpenSSL for operation-as-usual, and use CryptoAPI only for the certificate verification process. 可以将OpenSSL用于常规操作,而仅将CryptoAPI用于证书验证过程。 I see several threads around here on this topic, and most are tiptoed around/through. 我在此主题附近看到多个主题,并且大多数主题都围绕/贯穿。

With CryptoAPI you have to: 使用CryptoAPI您必须:

  • decode PEM to DER with CryptStringToBinary() , 使用CryptStringToBinary()PEM解码为DER
  • create a CERT_CONTEXT object with CertCreateCertificateContext() 使用CertCreateCertificateContext()创建一个CERT_CONTEXT对象
  • and verify the certificate in this form by well known/documented procedure. 并通过众所周知的/成文的程序以这种形式验证证书。 (For example here at ETutorials .) (例如, 此处为ETutorials的内容 。)

    For last step to work, you also need to initialize HCERTSTORE for one of MY , ROOT , CA system stores, or iterate through them... depending on the behavior you want. 为了使最后一步起作用,您还需要为MYROOTCA系统存储之一初始化HCERTSTORE ,或通过它们迭代……根据您想要的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM