【问题标题】:OpenSSL or LibreSSL C++ sample for client TLS connection用于客户端 TLS 连接的 OpenSSL 或 LibreSSL C++ 示例
【发布时间】:2015-07-11 07:18:48
【问题描述】:

我正在寻找 C++ 中的客户端 TLS 连接示例。最适合 Visual Studio,但老实说,它可以是任何编译器。我找到了几个 C 样本。但是没有人工作。我从 C 中的这个示例开始: https://wiki.openssl.org/index.php/SSL/TLS_Client

但它失败了

    res = BIO_do_connect(web);

如果我想连接到我自己的 node.js 服务器(使用直接 IP 地址)或使用 encrypted.google.com 作为 url 的“错误主机名查找”,请使用“系统库”。 使用 libressl 和 Visual Studio 2013。

下一站:http://fm4dd.com/openssl/sslconnect.htm

这里程序运行成功。但任何尝试在结尾写入 SSL 连接:

std::string json = "{'test':'huhu'}";

char buff[1024];
sprintf(buff, "POST /test.de HTTP/1.1 \nHost: test.de\nContent-Type: application/json\nContent-Length: %d\n\n", json.length());
std::string post = buff;

int snd = SSL_write(ssl, post.data(), post.length());
snd = SSL_write(ssl, json.data(), json.length());

强制服务器关闭连接(我不知道到底发生了什么,因为我现在不知道如何告诉 node.js 告诉我更多信息)。

所以我搜索了一个工作示例或如何使用在 C++ 中运行的自己的证书获取 TLS 连接

【问题讨论】:

  • 您可以查看主要 OpenSSL 命令行工具中的 s_client 代码。这支持很多证书选项。
  • 你应该知道最好不要要求教程或示例 :) 我经常使用 C++ 来包装 OpenSSL,但我使用唯一指针这样做,因此会自动进行清理。这是它的样子:How to properly print RSA* as string in C++?.
  • @jww 过失。今天下午我很绝望 :-) 现在看起来好多了。但是这个问题怎么办?删除它(诚实的问题)?
  • @Martin - 我认为这是您的选择(甚至认为这是一个很好的问题)。它不会累积反对票,因此允许它留下并可能关闭是没有害处的。如果它保持不变,那么其他人可以将其用作参考。 (由于网站政策,我投票关闭)。

标签: c++ openssl libressl


【解决方案1】:

我正在寻找 C++ 中的客户端 TLS 连接示例。

我认为有几个 OpenSSL 到 C++ 的端口。他们尝试做完整的类包装器。请在 Google 上查看 openssl++ class

当我在 C++ 中使用它时,我使用唯一指针进行清理。例如,参见How to properly print RSA* as string in C++?。我主要使用它来确保清理。我认为它类似于Resource Acquisition Is Initialization 模式。

OpenSSL 还为类似的库和框架提供了一个页面。请参阅 OpenSSL wiki 上的 Related Links 页面。


但它失败了

res = BIO_do_connect(web);

如果我想连接到我自己的 node.js 服务器(使用 > 直接 IP 地址)或使用“错误的主机名查找”,则使用“系统库”

我的猜测是证书中的名称与用于连接的 URL 中使用的名称不匹配。

您可以通过在host 文件中添加一个条目来使名称起作用。实际上,这是您的本地 DNS 覆盖。见Microsoft TCP/IP Host Name Resolution Order

或者,您可以生成包含所有必需名称的证书。为此,请参阅How to create a self-signed certificate with openssl?


强制服务器关闭连接(我不知道到底发生了什么,因为我现在不知道如何告诉 node.js 告诉我更多信息)。

 "POST /test.de HTTP/1.1 \nHost: test.de\nContent-Type: 
     application/json\nContent-Length: %d\n\n"

由于您缺少 Connection: close 请求标头,服务器可能正在关注RFC 7230, HTTP/1.1 Message Syntax and Routing, Section 6.1

不支持持久连接的服务器必须发送 每个响应消息中的“关闭”连接选项 有一个 1xx(信息)状态码。

另外,应该是这样的:

 "POST /test.de HTTP/1.1\r\nHost: test.de\r\nContent-Type: 
     application/json\r\nContent-Length:%d\r\n\r\n"

\r\n 用作新行,而不是 \r\n。双 \r\n 用于终止标头。您可以快速验证是否在标准中搜索 "CRLF"。您将参与 ABNF 语法的讨论。


所以我搜索了一个工作示例或如何使用在 C++ 中运行的自己的证书获取 TLS 连接

这里的诀窍是创建格式良好的证书。为此,请参阅How to create a self-signed certificate with openssl?

【讨论】:

    【解决方案2】:

    这是使用固定证书包的 LibreSSL 的更新示例:C++ libtls example on github

    【讨论】:

    • 这真的很糟糕,不是用 C++ 的角度写的。
    • 对,这是一个快速而肮脏的例子。开源的美妙之处在于,您可以采用它并制作一个更简洁的示例,让人们可能会欣赏。
    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 2021-07-28
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多