如何在 POCO C++ 库中正确使用 OpenSSL

Posted

技术标签:

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

根据 POCO 助手中的规范:

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

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

【问题讨论】:

【参考方案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;

【讨论】:

我注意到您没有将上下文传递给会话,这是故意的吗? 是的,将使用提供给 initializeClient() 的默认上下文:github.com/pocoproject/poco/blob/poco-1.7.8/NetSSL_OpenSSL/src/…【参考方案2】:

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

    打开 Makefile,将“PocoNetSSL”添加到 target_libs 将“HTTPClientSession”替换为“HTTPSClientSession” 您需要创建 Poco::Net::Context 以供 SSL 使用 替换'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);

总结:

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

【讨论】:

Context::VERIFY_NONE, "客户端:如果不使用匿名密码(默认禁用),服务器将发送一个将被检查的证书,但检查结果将被忽略。"这基本上不会破坏证书的意义吗? proteneer 说得好。更改为 verifyMode = Context::VERIFY_STRICT 和 loadDefaultCAs = true 似乎是更合理的默认设置。 VERIFY_NONE 以外的任何东西似乎确实比VERIFY_NONE 更安全,但是有些主机没有没有有效证书... :-(

以上是关于如何在 POCO C++ 库中正确使用 OpenSSL的主要内容,如果未能解决你的问题,请参考以下文章

C++ Poco - 如何创建 NotificationQueue 的向量?

在 C++ 谷物库中正确使用 CEREAL_REGISTER_DYNAMIC_INIT 问题

如何使用Poco :: ZIP压缩/解压缩zip文件

服务层如何适应我的存储库实现?

POCO怎么使用?

poco新增对cocos c++项目的支持~