https客户端使用客户端证书和密码与cpp-netlib一起获得 [英] https client get with cpp-netlib using a client certificate and password

查看:348
本文介绍了https客户端使用客户端证书和密码与cpp-netlib一起获得的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用cppnetlib,甚至使用boost asio库进行连接,以执行简单的url获取并将下拉的页面拉下.

I am trying to use cppnetlib, or even the boost asio libraries to connect to do a simple url get and pull the resulting page down.

我已经使其可以与http甚至https usign cppnetlib一起使用,但是我需要提供一个使用密码的客户端证书..Unforntuntley我需要使用较旧的v0.10 cppnetlib.

I have gotten it to work with http, and even https usign cppnetlib but I need to supply a client certitifcate that takes a password.. Unforntuntley I am required to use the older v0.10 cppnetlib.

这有可能吗?我认为答案是创建自己的_io_service并使用cert和密码为https请求自定义配置,然后将其提供给boost :: network :: http:client构造函数.以下内容可在http中使用,并且可在不要求证书的情况下用于https.

Is this possible to do. I think the answer is to create my own _io_service and custome configure it for the https request with cert and password and then supply that to the boost::network::http:client constructor. The below works in http, and will work for https without a cert requirement.

std::string url = "http://www.boost.org";
std::string certFile = "C:\\cert\\mycert.p12";
std::string password = "MyPassWord";
try {
        http::client client;
        http::client::request request(url);
        http::client::response response = client->get(request);

        std::string resultText = static_cast<std::string>(body(response));
        std::cout << resultText << std::endl;
        delete client;
    }
    catch (std::exception &e) {
        std::cerr << "Caught something connecting " << e.what() << std::endl;
    }

推荐答案

v0.10 cppnetlib不直接支持客户端证书.由于您使用的是cppnetleb,因此可以将boost asio与boost 1.49一起使用

v0.10 cppnetlib does not directly support client certifications. Since your using cppnetleb you can use boost asio with boost 1.49

这是一个示例代码,可以完成大部分的asio工作 https://github.com/alexandruc/SimpleHttpsClient/blob/master/https_client. cpp

Here is an example code that does most of the asio work https://github.com/alexandruc/SimpleHttpsClient/blob/master/https_client.cpp

该代码与 http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/example/ssl/client.cpp

我将两者都放在链接断开的情况下.处理https连接以进行客户端认证的过程,您需要在创建客户端之前在主函数中添加以下几行:

I am putting both in case the links break. That handles the https connection to do client certification you need to add the following lines to the main function before creating the client:

        std::string tempString = "test.pem"; //this is a pem file that contains a private key and a certificate. 

        boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23_client);
        ctx.set_options(boost::asio::ssl::context::default_workarounds
                                    | boost::asio::ssl::context::no_sslv2
                                    | boost::asio::ssl::context::no_sslv3);
        ctx.set_default_verify_paths();

        ctx.use_certificate_file(tempFileStr.c_str(), boost::asio::ssl::context_base::pem);
        ctx.use_private_key_file(tempFileStr.c_str(), boost::asio::ssl::context_base::pem);

但是,在此示例中,您没有PEM文件,而是p12文件(pkcs12格式). openssl可用于解密和创建所需的pem文件.我通过如何加载PKCS#12文件修改了以下代码不幸的是,此版本的boost不支持内存中的证书,因此必须将其写入或解密为文件.我将其放在temp目录中,并且可能应该在最后将其删除.

However in this example you do not have a PEM file but a p12 file, (pkcs12 format). openssl can be used to decrypt and create the deisred pem file. I adapted the code below from How to load a PKCS#12 file in OpenSSL programmatically? Unfortuntely this version of boost does not support certificates in memory so it has to be written, dycrypted to a file. I put this in the temp dir, and it should probably get deleted at the end.

std::string _certFile = "C:\\cert\\mycert.p12";
std::string password = "_certPassword";
boost::filesystem::path tempFile = boost::filesystem::temp_directory_path() / "temp.pem";
std::string tempFileStr = tempFile.generic_string();
std::cout<<"Using temp file " << tempFileStr<<std::endl;
try
    {

        //read in the pksc12 file, decode it and write a PEM file
        FILE *fp;
        EVP_PKEY *pkey;
        X509 *cert;
        STACK_OF(X509) *ca = NULL;
        PKCS12 *p12;
        int i;

        OpenSSL_add_all_algorithms();
        ERR_load_crypto_strings();
        if (!(fp = fopen(_certFile.c_str(), "rb"))) {
            fprintf(stderr, "Error opening file %s\n", _certFile);
            return false;       
        }
        p12 = d2i_PKCS12_fp(fp, NULL);
        fclose (fp);
        if (!p12) {
            fprintf(stderr, "Error reading PKCS#12 file\n");
            ERR_print_errors_fp(stderr);
            return false; 
        }
        if (!PKCS12_parse(p12, _certpPassword.c_str(), &pkey, &cert, &ca)) {
            fprintf(stderr, "Error parsing PKCS#12 file\n");
            ERR_print_errors_fp(stderr);
            return false; 

        }
        PKCS12_free(p12);
        if (!(fp = fopen(tempFileStr.c_str(), "w"))) {
            fprintf(stderr, "Error opening file %s\n", tempFileStr.c_str());
            return false; 
        }

        if (pkey) {
            fprintf(fp, "***Private Key***\n");
            PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
        }
        if (cert) {
            fprintf(fp, "***User Certificate***\n");
            PEM_write_X509(fp, cert);
        }
        if (ca && sk_X509_num(ca)) {
            fprintf(fp, "***Other Certificates***\n");

            for (i = 0; i < sk_X509_num(ca); i++) 
            {
                PEM_write_X509(fp, sk_X509_value(ca, i));
            }

        }

        sk_X509_pop_free(ca, X509_free);
        X509_free(cert);
        EVP_PKEY_free(pkey);    
        fclose(fp);

    }
    catch (std::exception &e) {
        retVal = false;
        std::cout <<"Error parsing/decrypting pkcs12 file into PEM or writing temporary pem file" << e.what() << std::endl;        
    }

这是我用过的物品

//for ssl connection
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/asio/ssl/context_base.hpp>

//for parsing key file
#include <openssl/pkcs12.h>

这篇关于https客户端使用客户端证书和密码与cpp-netlib一起获得的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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