【问题标题】:How to use OpenSSL in POCO C++ library correctly如何在 POCO C++ 库中正确使用 OpenSSL
【发布时间】:2012-06-08 05:01:32
【问题描述】:

根据 POCO 助手中的规范:

初始化 NetSSL 库,以及底层的 OpenSSL 库,通过调用 Poco::Crypto::OpenSSLInitializer::initialize()。 应该在使用 NetSSL 库中的任何类之前调用​​。 NetSSL 将自动初始化,通过 Poco::Crypto::OpenSSLInitializer 实例或类似机制 创建 Context 或 SSLManager 实例时。 但是,建议调用 initializeSSL() 无论如何在应用程序启动时。

当我想使用HTTPSClientSession时,我必须先构造一个Application对象吗? 如何在客户端中使用它?有大佬可以告诉我吗?非常感谢!

【问题讨论】:

    标签: c++ https openssl poco-libraries


    【解决方案1】:

    不,您不需要 Application 对象。这是一个功能齐全的示例:

    $ httpsget https://httpbin.org/user-agent
    {
      "user-agent": "Poco HTTPSClientSession"
    }
    

    代码:

    #include "Poco/StreamCopier.h"
    #include "Poco/URI.h"
    #include "Poco/Exception.h"
    #include "Poco/SharedPtr.h"
    #include "Poco/Net/SSLManager.h"
    #include "Poco/Net/KeyConsoleHandler.h"
    #include "Poco/Net/ConsoleCertificateHandler.h"
    #include "Poco/Net/HTTPSClientSession.h"
    #include "Poco/Net/HTTPRequest.h"
    #include "Poco/Net/HTTPResponse.h"
    #include <memory>
    #include <iostream>
    
    using namespace Poco;
    using namespace Poco::Net;
    
    class SSLInitializer {
    public:
        SSLInitializer() { Poco::Net::initializeSSL(); }
    
        ~SSLInitializer() { Poco::Net::uninitializeSSL(); }
    };
    
    int main(int argc, char** argv)
    {
        SSLInitializer sslInitializer;
    
        SharedPtr<InvalidCertificateHandler> ptrCert = new ConsoleCertificateHandler(false);
        Context::Ptr ptrContext = new Context(Context::CLIENT_USE, "", "", "rootcert.pem", Context::VERIFY_STRICT, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
        SSLManager::instance().initializeClient(0, ptrCert, ptrContext);
    
        try
        {
            if (argc > 1)
            {
                URI uri(argv[1]);
                HTTPSClientSession s(uri.getHost(), uri.getPort());
                HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPath());
                request.set("user-agent", "Poco HTTPSClientSession");
                s.sendRequest(request);
                HTTPResponse response;
                std::istream& rs = s.receiveResponse(response);
                StreamCopier::copyStream(rs, std::cout);
            }
        }
        catch (Exception& ex)
        {
            std::cout << ex.displayText() << std::endl;
            return 1;
        }
    
        return 0;
    }
    

    【讨论】:

    【解决方案2】:

    我们以Net/samples/httpget为例,我们将httpget/复制为一个新的httpsget目录:

    1. 打开 Makefile,将“PocoNetSSL”添加到 target_libs
    2. 将“HTTPClientSession”替换为“HTTPSClientSession”
    3. 您需要创建 Poco::Net::Context 以供 SSL 使用
    4. 替换'HTTPClientSession session(uri.getHost(), uri.getPort());'有以下两行:
    const Context::Ptr context = new Context(Context::CLIENT_USE, "", "", "", Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    HTTPSClientSession session(uri.getHost(), uri.getPort(), context);

    总结:

    1. 将 PocoNetSSL 添加为 lib_depends
    2. 将 Poco::Net::Context 与 HTTPSClientSession 一起使用

    【讨论】:

    • Context::VERIFY_NONE, "客户端:如果不使用匿名密码(默认禁用),服务器将发送一个将被检查的证书,但检查结果将被忽略。"这基本上不会破坏证书的意义吗?
    • proteneer 说得好。更改为 verifyMode = Context::VERIFY_STRICT 和 loadDefaultCAs = true 似乎是更合理的默认设置。
    • VERIFY_NONE 以外的任何东西似乎确实比VERIFY_NONE 更安全,但是有些主机没有没有有效证书... :-(
    猜你喜欢
    • 1970-01-01
    • 2017-06-07
    • 2015-02-17
    • 2022-01-07
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    相关资源
    最近更新 更多