【问题标题】:Unable to verify server certificate through Poco无法通过 Poco 验证服务器证书
【发布时间】:2014-09-16 00:12:24
【问题描述】:

我正在尝试在我的客户端中实施证书验证。 我总是收到SSL Exception: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed after 893ms,我确定它是有效的,尝试以这种方式获取 google.com 并失败了。我正在使用 RejectCertificateHandler 因为文档指出:

每当发生错误时都会调用 RejectCertificateHandler 验证证书。它总是拒绝证书。

只要发生错误,就会调用 AcceptCertificateHandler 验证证书。它始终接受证书。应该 仅用于测试目的。

我做错了什么?这是我的代码:

Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pAcceptCertHandler = new Poco::Net::RejectCertificateHandler(true);

Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(NULL, pAcceptCertHandler, pContext);

Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), pContext);
std::string path(uri.getPathAndQuery());

Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
initializeHttpGetRequest(request);
session.sendRequest(request);
session.setKeepAlive(true);

Poco::Timespan timespan(0, 0, 10, 0, 0);
session.setKeepAliveTimeout(timespan);

Poco::Net::HTTPResponse res;
std::istream & is = session.receiveResponse(res);

responseCode = res.getStatus();

【问题讨论】:

  • 我建议继承 InvalidCertificateHandler 并向我们展示输出,或者使用 ConsoleCertificateHandler 并向我们展示输出。这将有助于我们回答您的问题。无论哪种方式,问题都出在验证中,并且可能是您使用的密码列表。
  • WARNING: Certificate verification failed ---------------------------------------- Issuer Name: /C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root Subject Name: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA证书产生错误:无法获取本地颁发者证书
  • 您的机器中可能没有 Digicert 作为受信任的根权限。如果我们谈论的是 Windows,请查看 certmgr.msc。我相信这是你的问题。
  • 或者更简单 - 在 Chrome 或 IE 中打开此链接(不是 firefox,因为它使用自己的证书管理) - ev-root.digicert.com,看看它是否会产生错误。
  • 我在 Mac 上,在另一台机器上检查过,但如果每个人都必须手动信任它,那就太糟糕了。

标签: c++ ssl client poco


【解决方案1】:

经过进一步研究,我发现 Mac OS 的内置 OpenSSL 没有捆绑任何 CA 证书(它不使用系统钥匙串内的证书)。因此,无论您尝试验证什么主机,即使证书有效,也会失败。

我已将这些 CA 证书导出到单个 .pem 文件中,并将其与我的应用程序捆绑在一起。

现在,当我创建上下文时,我使用以下方法:

NSString *rootCA = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"rootCA.pem"];
Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", [rootCA UTF8String], verificationMode, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");

【讨论】:

  • 这些年来仍然很有帮助。谢谢。
猜你喜欢
  • 2015-10-19
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多