【问题标题】:What's wrong with the cpprestsdk https handshakecpprestsdk https 握手有什么问题
【发布时间】:2020-07-15 14:23:14
【问题描述】:

我申请了ssl,但结果并不理想。用wireshark查看时,服务端和客户端没有key变化。

可以交流,但不能令人满意。服务器是 Linux,客户端使用的是 Chrome。 我知道正常的ssl通信消息是

"客户端密钥交换、密码更改规范、加密握手消息"

服务器问候,证书,服务器密钥交换,服务器问候完成”。但它对我来说是不可见的。

代码

#include <iostream>
#include <cpprest/http_listener.h>
#include <cpprest/json.h>

using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;

int main(){
    http_listener_config listen_config;
    listen_config.set_ssl_context_callback([](boost::asio::ssl::context &ctx)
    {

        ctx.set_options(
            boost::asio::ssl::context::default_workarounds
            | boost::asio::ssl::context::no_sslv2
            | boost::asio::ssl::context::no_tlsv1
            | boost::asio::ssl::context::no_tlsv1_1
            | boost::asio::ssl::context::single_dh_use);
        ctx.set_password_callback([](std::size_t max_length, boost::asio::ssl::context::password_purpose purpose)
        {
           return "password";
        });
        ctx.use_certificate_chain_file("rootca.crt");
        ctx.use_private_key_file("rootca.key", boost::asio::ssl::context::pem);
        ctx.use_tmp_dh_file("dh2048.pem");
    });


    listen_config.set_timeout(utility::seconds(10));
    http_listener listener(U("https://0.0.0.0:10022"), listen_config);        //Server URL, Port .
        listener.support(methods::GET, [](http_request req){
        auto j = json::value::object();
        auto path = req.request_uri().path();
        std::cout << path << std::endl;
        j[U("one")] = json::value::string(U("asdfasefasdfaefasdfasefasdfefasefasefaqf3wfsefasdfasefasdfzsfzdfaesfzsefzsdfzsef"));
        req.reply(status_codes::OK, j);                     
        });
    
    listener.open().then([&listener](){std::cout << (U("\n start!!\n"));}).wait();    //Server open
    while(true);
    listener.close();
    return 0;
    
}

客户端连接服务器时的数据包。

这段代码有问题吗?或者这是正常的吗?

【问题讨论】:

    标签: c++ boost-asio cpprest-sdk


    【解决方案1】:

    不,这样不行:

    做一个

    openssl s_client -connect :10022 -debug -showcerts -state
    

    表演

    CONNECTED(00000005)
    write to 0x5614f8b23690 [0x5614f8b33620] (311 bytes => 311 (0x137))
    0000 - 16 03 01 01 32 01 00 01-2e 03 03 79 fe 76 37 2b   ....2......y.v7+
    0010 - 9f bf e7 62 51 34 7d 4a-00 5e 1f ed 55 64 61 e1   ...bQ4}J.^..Uda.
    0020 - 44 ce a0 c0 31 eb 3a b0-80 78 87 20 70 c4 1f 56   D...1.:..x. p..V
    0030 - 62 da 74 b7 d7 6a 31 50-0c 8c 90 46 23 c6 59 13   b.t..j1P...F#.Y.
    0040 - 17 6c 67 8f e3 9a 85 77-ab 6e c2 a3 00 3e 13 02   .lg....w.n...>..
    0050 - 13 03 13 01 c0 2c c0 30-00 9f cc a9 cc a8 cc aa   .....,.0........
    0060 - c0 2b c0 2f 00 9e c0 24-c0 28 00 6b c0 23 c0 27   .+./...$.(.k.#.'
    0070 - 00 67 c0 0a c0 14 00 39-c0 09 c0 13 00 33 00 9d   .g.....9.....3..
    0080 - 00 9c 00 3d 00 3c 00 35-00 2f 00 ff 01 00 00 a7   ...=.<.5./......
    0090 - 00 00 00 0e 00 0c 00 00-09 6c 6f 63 61 6c 68 6f   .........localho
    00a0 - 73 74 00 0b 00 04 03 00-01 02 00 0a 00 0c 00 0a   st..............
    00b0 - 00 1d 00 17 00 1e 00 19-00 18 00 23 00 00 00 16   ...........#....
    00c0 - 00 00 00 17 00 00 00 0d-00 30 00 2e 04 03 05 03   .........0......
    00d0 - 06 03 08 07 08 08 08 09-08 0a 08 0b 08 04 08 05   ................
    00e0 - 08 06 04 01 05 01 06 01-03 03 02 03 03 01 02 01   ................
    00f0 - 03 02 02 02 04 02 05 02-06 02 00 2b 00 09 08 03   ...........+....
    0100 - 04 03 03 03 02 03 01 00-2d 00 02 01 01 00 33 00   ........-.....3.
    0110 - 26 00 24 00 1d 00 20 a1-ab 9c 0d 7e e9 80 84 ba   &.$... ....~....
    0120 - 0a 5a 71 20 7d 59 cd d9-24 9c de 9a 05 9d a2 78   .Zq }Y..$......x
    0130 - 0d 0d 79 a1 3b 65 58                              ..y.;eX
    read from 0x5614f8b23690 [0x5614f8b2a313] (5 bytes => 0 (0x0))
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 0 bytes and written 311 bytes
    Verification: OK
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    Early data was not sent
    Verify return code: 0 (ok)
    ---
    read from 0x5614f8b23690 [0x5614f8b18d80] (8192 bytes => 0 (0x0))
    

    所以我得到了不安全的回退。事实证明,未处理的异常会导致真正退化的行为。添加一些异常处理显示:

    ERROR: use_certificate_chain_file: No such file or directory
    

    嗯,当然。添加这些:

    注意:您似乎不太可能实际使用 rootca 作为服务器。也许更改文件的名称以反映它包含的内容,或者重新考虑您用于服务器目的的证书。

            ctx.set_password_callback(
                [](std::size_t /*max_length*/,
                   ssl::context::password_purpose /*purpose*/) {
                    return "test";
                });
            ctx.use_certificate_chain_file("server.pem");
            ctx.use_private_key_file("server.pem", ssl::context::pem);
            ctx.use_tmp_dh_file("dh2048.pem");
    

    注意,我使用了 boost SSL 示例中的 key/dh 参数,所以密码是 test

    现在,一个简单的 GET 请求可以工作了,可以再次使用 s_client 或使用类似 wget 的东西:

    wget --no-check-certificate https://localhost:10022/ -O - -q
    {"one":"asdfasefasdfaefasdfasefasdfefasefasefaqf3wfsefasdfasefasdfzsfzdfaesfzsefzsdfzsef"}
    

    总结

    我的假设是,您也陷入了不处理错误的陷阱。我认为库的“失败打开”模式是一个潜在的安全问题——尽管ssl::context 的所有这些参数可能一直有效地要求这样做。


    作为参考,我最后测试的完整代码:

    #include <cpprest/http_listener.h>
    #include <cpprest/json.h>
    #include <iostream>
    
    using namespace web;
    using namespace web::http;
    using namespace web::http::experimental::listener;
    namespace net = boost::asio;
    namespace ssl = net::ssl;
    
    int main() {
        http_listener_config listen_config;
        listen_config.set_ssl_context_callback([](ssl::context& ctx) {
            try {
                std::clog << "set_ssl_context_callback" << std::endl;
                ctx.set_options(ssl::context::default_workarounds |
                                ssl::context::no_sslv2 | ssl::context::no_tlsv1 |
                                ssl::context::no_tlsv1_1 |
                                ssl::context::single_dh_use);
                ctx.set_password_callback(
                    [](std::size_t /*max_length*/,
                       ssl::context::password_purpose /*purpose*/) {
                        return "test";
                    });
                ctx.use_certificate_chain_file("server.pem");
                ctx.use_private_key_file("server.pem", ssl::context::pem);
                ctx.use_tmp_dh_file("dh2048.pem");
                std::clog << "leave set_ssl_context_callback" << std::endl;
            } catch (std::exception const& e) {
                std::clog << "ERROR: " << e.what() << "\n";
            }
        });
    
        listen_config.set_timeout(utility::seconds(10));
        http_listener listener(U("https://localhost:10022"),
                               listen_config); // Server URL, Port .
    
        listener.support(methods::GET, [](http_request req) {
            std::clog << "enter handler" << std::endl;
            auto j = json::value::object();
            auto path = req.request_uri().path();
            std::clog << path << std::endl;
            j[U("one")] =
                json::value::string(U("asdfasefasdfaefasdfasefasdfefasefasefaqf3wfs"
                                      "efasdfasefasdfzsfzdfaesfzsefzsdfzsef"));
            req.reply(status_codes::OK, j).wait();
            std::clog << "leave handler" << std::endl;
        });
    
        listener.open()
            .then([&listener] { std::clog << (U("\n start!!\n")); })
            .wait(); // Server open
        while (true)
            ;
        listener.close(); // huh
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多