如何在 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 的向量?