【问题标题】:my https C++ code doesn't work on some sites (binance)我的 https C++ 代码在某些网站上不起作用(binance)
【发布时间】:2018-04-20 20:11:18
【问题描述】:

我使用 OpenSSL 在 C++ 中创建了一个 https 类。它适用于大多数网站/网址,但不适用于以下网站/网址:

我可以使用浏览器/wget/postman 打开它们,所以它们不是坏链接。 我也确定我的请求/标头是有效且正确的。 我怀疑 SSL 版本有问题,但我尝试了 OpenSSL 中的所有版本但没有运气(SSLv3、TLS 1.1/1.2)

即使在我发送标头之前,服务器也会立即关闭我的连接。

这是我的请求的示例,我认为这没有错。 因为我找不到任何错误,并且相同的代码适用于其他网站/网址。

GET /api/v1/exchangeInfo HTTP/1.1
Accept: */*
Accept-Encoding: gzip,deflate
Connection: keep-alive
Host: api.binance.com
User-Agent: evo

我不知道是什么原因造成的。有谁知道为什么?

谢谢!!

  SslSocket ssl;
  st = ssl.create();
  st = ssl.connect("api.binance.com:443");

  const char* req_header = "GET /api/v1/exchangeInfo HTTP/1.1\r\n"
      "Host: " "api.binance.com" "\r\n"
      "\r\n";
  st = ssl.send(req_header, strlen(req_header));

  while (true){
      char buff[ 1024 ] = {};
      size_t recv_size = 0;
      st = ssl.recv(recv_size, buff, sizeof(buff) - 1);
      if (!st) break;

      if (recv_size > 0)
          fwrite(buff, 1, recv_size, stdout);
  }

我做了这样的事情来设置我的 ssl 套接字:

const SSL_METHOD *method = SSLv23_client_method(); 
_ctx = SSL_CTX_new(method);
_ssl = SSL_new(_ctx);
SSL_set_fd(_ssl, _socket.fd());
_socket.connect(addr);
SSL_connect(_ssl);
printf("SSL_get_version2: %s\n", SSL_get_version(_ssl));

【问题讨论】:

  • 为什么不将请求中的 HTTP 请求标头与浏览器开发工具中的请求标头进行比较?并让您的请求使用相同的字段。如果它不起作用,那么您在某处使用 OpenSSL 时出错了。
  • 请发布一个最小的示例代码,在没有提供最少信息的情况下向某人提问是不礼貌的。
  • 我尝试发送确切的请求标头,但不起作用
  • 记录与 Wireshark 的通信。这将告诉您 SSL 密码协商和密钥交换是否成功。我几乎可以肯定它不是。你也会找到原因。
  • 我用wireshark试过了,但是因为它是加密的,我怎么知道?

标签: c++ ssl https openssl cryptocurrency


【解决方案1】:

此站点要求客户端使用 SNI 扩展。如果没有 SNI 扩展,你会得到这个:

$ openssl s_client -connect api.binance.com:443
...
140269619467928:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:772:
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000

使用 SNI 扩展,您可以得到:

$ openssl s_client -connect api.binance.com:443 -servername api.binance.com
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256

要在您的代码中使用 SNI,请使用 SSL_set_tlsext_host_name。这个功能的使用方法见this code in s_client.c

【讨论】:

  • 哦,是的,现在可以使用了!!!谢谢史蒂芬!!!我现在才知道 SNI 是什么。
  • 不错。您如何确定这是问题所在?
  • @AndrewHenle:我经常看到类似的问题。需要 SNI 的服务器是更常见的问题之一,并且可以使用我在答案中的 openssl 命令轻松检查。也被SSLLabs举报。
猜你喜欢
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-23
  • 1970-01-01
相关资源
最近更新 更多