与Boost.Asio的和OpenSSL HTTPS请求 [英] HTTPS request with Boost.Asio and OpenSSL

查看:3259
本文介绍了与Boost.Asio的和OpenSSL HTTPS请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想阅读 https://mtgox.com/api/0/data股票代码/ticker.php 从我的C ++应用程序。
我使用Boost.Asio的和OpenSSL,因为该服务需要HTTPS。

加速版本:1.47.0

OpenSSL:已1.0.0d [2011年2月8日]的Win32

有关申请;我从这个例子<一个href=\"http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp\">http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp
上手修改,如下所示:

这就是我想要连接到:

 的boost ::支持ASIO ::知识产权:: TCP ::解析::查询查询(mtgox.com,443);

我设置验证,因为没有握手,否则失败。我不知道这是mtgox一个问题或者说这是实现真正严格,因为当我打印证书到屏幕上看起来合法的(和来访的股票页面时铬有没有问题的话)。

  socket_.set_verify_mode(提高:: ASIO :: SSL ::背景:: VERIFY_NONE);

这是我送的要求:

 的std :: stringstream的REQUEST_;REQUEST_&LT;&LT; GET /api/0/data/ticker.php HTTP / 1.1 \\ r \\ n;
REQUEST_&LT;&LT; 主持人:mtgox.com \\ r \\ n;
REQUEST_&LT;&LT; 的Accept-Encoding:* \\ r \\ n;
REQUEST_&LT;&LT; \\ r \\ n;提高:: ASIO :: async_write(socket_,提高:: ASIO ::缓​​冲区(request_.str()),提高::绑定(安培;客户:: handle_write,为此,提高:: ASIO ::占位符::错误提高:: ASIO ::占位符:: bytes_transferred));

(满code: http://pastebin.com/zRTTqZVe

我遇到了以下错误:

 连接OK!
验证:
/ C = IL / O = StartCom Ltd./OU=Secure数字证书签名/ CN = StartCom认证机构
发送请求:
GET /api/0/data/ticker.php HTTP 1.1
主持人:mtgox.com
接受编码:*发送请求OK!读取失败:一个现有的连接被强行关闭远程主机

我在这个正确的方向前进?该错误消息是不是真的描述的问题,我不知道我做到了哪一步错了。

在此先感谢!

更新:
我用卷曲,看看哪里出了问题:

 卷曲--trace-ascii的out.txt https://mtgox.com/api/0/data/ticker.php

(全功率输​​出: http://pastebin.com/Rzp0RnAK
它在验证过程中失败。
当我用不安全连接参数

 卷曲--trace-ascii的out.txt -k https://mtgox.com/api/0/data/ticker.php

(全功率输​​出: http://pastebin.com/JR43A7ux

一切工作正常。

修正:


  1. 我固定的错字在HTTP头文件

  2. 我加了根证书,
    打开SSL验证功能。


解决方案

在短:


  1. 您发送HTTP 1.1,而不是HTTP / 1.1。这当然足以让服务器拒绝你的要求。有您的要求和卷曲的之间的其他差异,您可能需要更改这些PARAMS以及 - 即使他们似乎有效,以我


  2. 也许OpenSSL的不具备服务器,不像Chrome的使用的根证书,这就是为什么验证失败。


详细内容:


  1. 由于工作和非工作的工具,你应该总是比较发生了什么。在这里,你有卷曲的产量和你的要求 - 比较它们表现出一些差异;通常情况下,即使有加密连接时,可以使用功能强大的数据包嗅探器像Wireshark的,其中德codeS从包尽可能多的信息。这将允许看到服务器实际发送的数据包少(我希望);另一种可能性本来是(因为客户端有一些bug说)你的客户没有得到服务器发送的数据。


  2. 如果我理解正确的,为什么你需要禁用验证,右卷曲仅表现?该证书看起来有效期为我的铬为好,但根证书颁发机构是相当不明;卷曲提到了CA证书,即权威认证的证书。根证书信任,因为它已经是美元的客户端上的证书DB P中$ psent - 我认为Chrome的可能比OpenSSL的(这被两个卷曲和你的程序),更完整的DB

    <。 / LI>

I'm trying to read the ticker symbol at https://mtgox.com/api/0/data/ticker.php from my C++ application. I use Boost.Asio and OpenSSL because the service requires HTTPS.

Boost version: 1.47.0

OpenSSL: 1.0.0d [8 Feb 2011] Win32

For the application; I took the example from http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp to get started and modified it as follows:

This is where I want to connect to:

boost::asio::ip::tcp::resolver::query query("mtgox.com", "443");

I set verification to none because the handshake fails otherwise. I'm not sure if this is a problem with mtgox or that this implementation is really strict because when I print the certificate to the screen it looks legit (and chrome has no problem with it when visiting the ticker page).

socket_.set_verify_mode(boost::asio::ssl::context::verify_none);

This is the request I send:

std::stringstream request_;

request_ << "GET /api/0/data/ticker.php HTTP/1.1\r\n";
request_ << "Host: mtgox.com\r\n";
request_ << "Accept-Encoding: *\r\n";
request_ << "\r\n";

boost::asio::async_write(socket_, boost::asio::buffer(request_.str()), boost::bind(&client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

(full code: http://pastebin.com/zRTTqZVe)

I run into the following error:

Connection OK!
Verifying:
/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
Sending request: 
GET /api/0/data/ticker.php HTTP 1.1
Host: mtgox.com
Accept-Encoding: *

Sending request OK!

Read failed: An existing connection was forcibly closed by the remote host

Am I going in the right direction with this? The error message isn't really descriptive of the problem and I don't know which step I did wrong.

Thanks in advance!

Update: I used cURL to see what went wrong:

curl --trace-ascii out.txt https://mtgox.com/api/0/data/ticker.php

(full output: http://pastebin.com/Rzp0RnAK) It fails during verification. When i connect with the "unsafe" parameter

curl --trace-ascii out.txt -k https://mtgox.com/api/0/data/ticker.php

(full output: http://pastebin.com/JR43A7ux)

everything works fine.

Fix:

  1. I fixed the typo in the HTTP headers
  2. I added a root certificate and turned SSL verification back on.

解决方案

In short:

  1. You send "HTTP 1.1" instead of "HTTP/1.1". That's surely enough to make the server refuse your request. There are other differences between your request and cURL's, you might need to change those params as well - even if they seem valid to me.

  2. Maybe OpenSSL does not have the root certificate used by the server, unlike Chrome, and that's why verification is failing.

Details:

  1. Given a working and non-working tool, you should always compare what's happening. Here you have cURL's output and your request - comparing them showed a number of differences; usually, even with an encrypted connection, you can use a powerful packet sniffer like Wireshark, which decodes as much information from the packets as possible. Here it would allow to see that the server is actually sending less packets (I expect); another possibility would have been that your client was not getting the data sent by the server (say because the client had some bug).

  2. If I understand correctly, curl showed only why you needed to disable verification, right? The certificate looks valid for me on chrome as well, but the root certification authority is quite unknown; curl mentions the "CA cert", i.e. the certificate of the certification authority. The root certificate is trusted because it is already present in a certificate DB on the client - I think that Chrome might have a more complete DB than OpenSSL (which is used by both cURL and your program).

这篇关于与Boost.Asio的和OpenSSL HTTPS请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆